codeforces #299 div 2
(总算是5题都做完了- -)
暂时做了4题,先放一下有时间做最后一题(当然如果我真的能做出的话。。。)(看了大神的代码总算是理解了E题,做完发现也没那么难,果然想出一个思路的过程对于我这种弱渣来说还是太强求了啊。。。)
A题:
英文单词别拼错就没什么问题吧
#include <cstdio>
#include <cstring> using namespace std; char str[][] = {"" , "" , "twenty" , "thirty" , "forty" , "fifty" , "sixty" , "seventy" ,"eighty" , "ninety"};
char single[][] = {"zero" , "one","two","three","four","five","six","seven","eight","nine"};
char dou[][] = {"ten" ,"eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"};
int main()
{
int x;
while(~scanf("%d" , &x)){
if(x<){
printf("%s\n" , single[x]);
}
else if(x<){
printf("%s\n" , dou[x%]);
}
else{
int tmp = x%;
printf("%s" , str[x/]);
if(tmp){
printf("-%s" , single[tmp]);
}
printf("\n");
}
}
return ;
}
B题:
给定一个1~n的范围,问这个范围内只包含4或者7的数字有多少个
假设n是一个长度为l的整数,那么肯定所有 <l 长度的整数包含4,7的都能取到
就是(2^1+2^2+...2^(l-1))
那么就要确定 l 位整数的情况,不断从前往后按照那时的位置上的数字进行判断
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int dig[]; int qpow(int digit)
{
int a= , b=digit , ans=;
while(b)
{
if(b&) ans*=a;
a*=a;
b>>=;
}
return ans;
} int getDigit(int x)
{
int ans=;
while(x){
x/=;
ans++;
}
return ans;
} void getHead(int x , int len)
{
int index=len;
while(x){
dig[index--]=x%;
x/=;
}
} int main()
{
int n;
while(~scanf("%d" , &n))
{
int len = getDigit(n);
int ans=;
for(int i= ; i<=len- ; i++)
ans+= qpow(i);
if(ans == ) ans-=;
getHead(n , len);
for(int i= ; i<=len ; i++){
// cout<<dig[i]<<endl;
if(dig[i]>){
ans += qpow(len-i+);
break;
}
else if(dig[i] == ){
ans += qpow(len-i);
if(i == len) ans+=;
}
else if(dig[i]>){
ans += qpow(len-i);
break;
}
else if(dig[i]==){
if(i == len) ans+=;
continue;
}
else break;
}
printf("%d\n" , ans);
}
return ;
}
C题:
一个二分题,当且仅当t在,第一个数时输出-1 , 否则二分判断 t>=最大数,且所有数之和<=t*m即可,这个略微想一下就好了,注意乘法溢出,我在这一直wa
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define N 1000005
int l,t,m;
int a , b , n;
#define ll long long bool check(int mid)
{
ll cnt = mid-l+;
ll st = a+(ll)(l-)*b , la=(ll)(mid-)*b+a;
if(t>=la && (st+la)*cnt/<=(ll)t*m) return true;
else return false;
} int bin_search()
{
if(a+(ll)(l-)*b > (ll)t) return -;
int left = l , right = N , ans = l;
while(left<=right)
{
int mid = left+(right-left)/;
if(check(mid)){
left = mid+;
ans = mid;
}else right=mid-;
}
return ans;
} int main()
{
// freopen("a.in" , "r" , stdin); while(~scanf("%d%d%d" , &a , &b , &n))
{
for(int i= ; i<=n ; i++){
scanf("%d%d%d" , &l , &t , &m);
printf("%d\n" , bin_search());
}
}
return ;
}
D题:
后缀数组题,这里虽然一看就想到暴力,但是看一下时间复杂度就呵呵了
利用后缀数组判断当前位置插入一个新的p , 覆盖前一个p的时候是否有冲突即可
当前位置 cur , 其实就是判断cur的后缀是不是 0 开头的子串
然后就用vis[]保存插在当前点是否影响即可
然后i=1~m按顺序查询,单位时间内就解决了
这里各种特殊情况要考虑,我太欠缺考虑了,完全是依赖cf上可以错了看数据慢慢改对的。。。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define N 1000005
#define ll long long
const int MOD = 1e9+; char str[N];
int a[N] , n , m;
int r[N] , sa[N] , height[N] , rank[N] , wa[N] , wb[N] , wsf[N] , wv[N];
bool vis[N]; int cmp(int *r , int a , int b , int l)
{
return r[a]==r[b] && r[a+l]==r[b+l];
} void get_sa(int *r , int *sa , int n , int m)
{
int *x=wa , *y=wb , *t;
int i,j,p;
for(i= ; i<m ; i++) wsf[i]=;
for(i= ; i<n ; i++) wsf[x[i]=r[i]]++;
for(i= ; i<m ; i++) wsf[i]+=wsf[i-];
for(i=n- ; i>= ; i--) sa[--wsf[x[i]]]=i; p= ;
for(j= ; p<n ; j*= , m=p){
for(p= , i=n-j ; i<n ; i++) y[p++] = i;
for(i= ; i<n ; i++) if(sa[i]>=j) y[p++]=sa[i]-j; for(i= ; i<n ; i++) wv[i]=x[y[i]];
for(i= ; i<m ; i++) wsf[i]=;
for(i= ; i<n ; i++) wsf[wv[i]]++;
for(i= ; i<m ; i++) wsf[i]+=wsf[i-];
for(i=n- ; i>= ; i--) sa[--wsf[wv[i]]]=y[i]; t=x , x=y , y=t;
x[sa[]]=;
for(p= , i= ; i<n ; i++)
x[sa[i]] = cmp(y , sa[i-] , sa[i] , j)?p-:p++;
}
} void callHeight(int *r , int *sa , int n , int m)
{
int i , j , k=;
for(i= ; i<=n ; i++) rank[sa[i]]=i;
for(i= ; i<n ; height[rank[i++]]=k)
for(k?k--: , j=sa[rank[i]-] ; r[i+k] == r[j+k] ; k++) ;
return;
} void biaoji(int n)
{
memset(vis , , sizeof(vis));
vis[]=true;
int order = ; //记录以开头为起点的排名
for(int i= ; i<=n ; i++){
if(sa[i] == ) order = i;
}
int len=N;
for(int i=order ; i>= ; i--){
int pos = sa[i-];
len = min(len , height[i]);
if(pos+len>=n) vis[pos]=true;
}
len=N;
for(int i=order+ ; i<=n ; i++){
int pos = sa[i];
len = min(len , height[i]);
if(pos+len>=n) vis[pos]=true;
}
} int qpow(int cnt)
{
if(!cnt) return ;
ll ans = , a = ;
while(cnt)
{
if(cnt&) ans = (ans*a)%MOD;
a = (a*a)%MOD;
cnt>>=;
}
return (int)ans;
} int main()
{
// freopen("a.in" , "r" , stdin); while(~scanf("%d%d" , &n , &m))
{
scanf("%s" , str);
for(int i= ; i<m ; i++) scanf("%d" , a+i);
sort(a , a+m); int len = strlen(str);
for(int i= ; i<len ; i++){
r[i] = (int)str[i];
}
r[len]=;
get_sa(r , sa , len+ , );
callHeight(r , sa , len , );
biaoji(len); int cnt = a[]-;
bool flag = true;
for(int i= ; i<m ; i++){
int dis = a[i]-a[i-];
if(dis>=len){
cnt+=dis-len;
}else{
if(!vis[dis]) {
// cout<<i<<" "<<dis<<endl;
flag = false;
break;
}
}
}
cnt+=n+-a[m-]-len;
int ans;
if(!flag){
// cout<<"exist "<<endl;
ans = ; }
else if(m == ){
ans = qpow(n);
}
else{
// cout<<"no "<<endl;
if(cnt)
ans = qpow(cnt);
else ans=;
}
printf("%d\n" , ans);
}
return ;
}
E题:
题目大意就是希望找到一个可能的游泳长度和跑步长度,对应那个队员的两种速度使其有机会夺冠,输出可能夺冠的队员编号
我们很容易就能想到,如果一个队员其中一项速度是最大的,那么他必然是能夺冠的
我们从游泳速度从上到下依次将当前跑步所能达到最快速度的人添加进入数组,结构体只保存s(swimming) , r(running)
当我们每次添加进一个元素时,当前元素是因为跑步最快所以不用删除,那么如果数组中除了游泳最快的那个无需考虑,中间的队员两个速度被夹在中间,此时要考虑能不能存在一个这样的lenS , lenR 使其夺冠
每次拿三个人的只进行考虑
比如这里举例 s1:1 , r1:3 s2:2,r2:2 s3:3,r3:1
那么假设这样的长度存在,设游泳长度为x , 跑步长度为y
那么
t1=x/1+y/3
t2=x/2+y/2
t3=x/3+y/1
2号能夺冠,那么t2<=t1 && t2<=t3
t2<=t1-> x/y>=(1/2-1/3)/(1/1-1/2) = 1/3
t2<=t3 -> x/y<=(1/1-1/2)/(1/2-1/3) = 3/1
那么 1/3<=x/y<=3/1 成立,所以2号能夺冠
根据上述例子就可以自己计算了
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <set>
#include <map>
using namespace std;
#define N 10000
#define ll long long
#define eps 1e-9
int run[N*+]; //游泳速度为i的人中跑步速度最快达到run[i] struct Ath{
int s , r;
Ath(int s= , int r=):s(s),r(r){}
}ath[N*+];
int k , s[N*+] , r[N*+]; bool can_win(int s1 , int r1 , int s2 , int r2 , int s3 , int r3)
{
//s1<s2<s3 , r1>r2>r3 , 判断s2,r2在包夹下能否有机会夺冠
double t1 = (1.0/r2-1.0/r1) / (1.0/s1-1.0/s2); double t2 = (1.0/r3-1.0/r2) / (1.0/s2-1.0/s3);
// cout<<t1<<" "<<t2<<endl;
if(t2-t1>=-eps) return true;
else return false;
} int main()
{
// freopen("a.in" , "r" , stdin);
int n;
while(~scanf("%d" , &n))
{
memset(run , , sizeof(run)); for(int i= ; i<=n ; i++){
scanf("%d%d" , &s[i] , &r[i]);
run[s[i]] = max(run[s[i]] , r[i]);
}
k=;
int i;
for(i=N ; i>= ; i--){
if(run[i]){
ath[k++] = Ath(i , run[i]);
break;
}
}
for(i=i- ; i>= ; i--){
run[i] = max(run[i] , run[i+]);
if(run[i] > run[i+]){
while(k>){
if(!can_win(i , run[i] , ath[k-].s , ath[k-].r , ath[k-].s , ath[k-].r)){
k--;
}else
break;
}
ath[k++] = Ath(i , run[i]);
}
}
map<int , int> m;
for(int i= ; i<k ; i++){
m[ath[i].s] = ath[i].r;
}
bool flag=true;
for(int i= ; i<=n ; i++){
if(m[s[i]] == r[i]){
if(flag) printf("%d" , i);
else printf(" %d" , i);
flag = false;
}
}
puts("");
}
return ;
}
codeforces #299 div 2的更多相关文章
- 二分搜索 Codeforces Round #299 (Div. 2) C. Tavas and Karafs
题目传送门 /* 题意:给定一个数列,求最大的r使得[l,r]的数字能在t次全变为0,每一次可以在m的长度内减1 二分搜索:搜索r,求出sum <= t * m的最大的r 详细解释:http:/ ...
- 水题 Codeforces Round #299 (Div. 2) A. Tavas and Nafas
题目传送门 /* 很简单的水题,晚上累了,刷刷水题开心一下:) */ #include <bits/stdc++.h> using namespace std; ][] = {" ...
- DFS Codeforces Round #299 (Div. 2) B. Tavas and SaDDas
题目传送门 /* DFS:按照长度来DFS,最后排序 */ #include <cstdio> #include <algorithm> #include <cstrin ...
- Codeforces #344 Div.2
Codeforces #344 Div.2 Interview 题目描述:求两个序列的子序列或操作的和的最大值 solution 签到题 时间复杂度:\(O(n^2)\) Print Check 题目 ...
- Codeforces #345 Div.1
Codeforces #345 Div.1 打CF有助于提高做题的正确率. Watchmen 题目描述:求欧拉距离等于曼哈顿距离的点对个数. solution 签到题,其实就是求有多少对点在同一行或同 ...
- Codeforces Beta Round #27 (Codeforces format, Div. 2)
Codeforces Beta Round #27 (Codeforces format, Div. 2) http://codeforces.com/contest/27 A #include< ...
- Codeforces#441 Div.2 四小题
Codeforces#441 Div.2 四小题 链接 A. Trip For Meal 小熊维尼喜欢吃蜂蜜.他每天要在朋友家享用N次蜂蜜 , 朋友A到B家的距离是 a ,A到C家的距离是b ,B到C ...
- codeforces #592(Div.2)
codeforces #592(Div.2) A Pens and Pencils Tomorrow is a difficult day for Polycarp: he has to attend ...
- codeforces #578(Div.2)
codeforces #578(Div.2) A. Hotelier Amugae has a hotel consisting of 1010 rooms. The rooms are number ...
随机推荐
- 前端打印console
很多时候,我们都想知道,是否已经选中或得到数据时,我们可以利用console 打印出来.console有几种方式使用.具体有: console.log($scope.getParkId); conso ...
- P1838 三子棋I
题目描述 小a和uim喜欢互相切磋三子棋.三子棋大家都玩过是吗?就是在九宫格里面OOXX(别想歪了),谁连成3个就赢了. 由于小a比较愚蠢,uim总是让他先. 我们用9个数字表示棋盘位置: 123 4 ...
- git push时报错filename too long的解决
命令行输入:git config core.longpaths true 之后再进行 git 的push命令
- sqlserver2012 offset
/* * Hibernate, Relational Persistence for Idiomatic Java * * License: GNU Lesser General Public Lic ...
- DBMS数据库语言
https://www.yiibai.com/dbms/dbms-language.html DBMS具有适当的语言和接口来表达数据库查询和更新.数据库语言可用于读取,存储和更新数据库中的数据. 数据 ...
- Unity3D 在自定义脚本中实现Button组件上的OnClick面板
下述内容不对c#语法做过多讲解,仅对已入门并有兴趣的同学做为学习和拓展的资料 大家在Unity制作的过程中一定都使用过UI功能,那么很多人也一定见过这个面板: 那么我们如何能在自己的脚本中添加上像On ...
- Cocos工程命名规则整理(node部分)
CocosCreator工程内的命名工程节点的命名规则工程内节点是程序调用资源的主要凭证,一套统一的命名方式和结构可以很大程度降低程序使用Cocos工程的难度 CocosCreator工程是由node ...
- shell 数值比较和字符串比较
1. 数值比较 -eq 是否相等(equal) -gt 是否大于(greater than) -ge 是否大于等于(greater and equal tha ...
- c++调用com口操作autocad
#include "stdafx.h" #include <atlcomcli.h> #import "D:\\C++test\\FirstCom\\Rele ...
- GetForgroundWindow函数的不确定性——BUG笔记
HWND GetForgoundWindows() 获取当前前置窗口在windows 7和windows 10下虚拟桌面切换后表现不同. 所以强烈不建议使用此函数!