Codeforces Round #427 (Div. 2)—A,B,C,D题
A. Key races
题目链接:http://codeforces.com/contest/835/problem/A
题目意思:两个比赛打字,每个人有两个参数v和t,v秒表示他打每个字需要多久时间,等这个这个字传递过去需要t秒,而且在打第一个字之前也会有一个反应时间t。问第一个人可不可以获胜。
题目思路:这个题目当时题目没读懂,明白之后就是一个非常简单的题目了。
(s*v1+2*t1)<(s*v2+2*t2)第一个人就可以获胜
(s*v1+2*t1)==(s*v2+2*t2) 就会平局,否则第二个人获胜。
每个人完成任务的时间为,v*s+2*t,打s个字的需要的时间s*v,开始的时候的反应的时间t,最后一个字打完以后还需要t的时间才结束。
代码:
1 //Author: xiaowuga 2 #include <iostream> 3 #include <algorithm> 4 #include <set> 5 #include <vector> 6 #include <queue> 7 #include <cmath> 8 #include <cstring> 9 #include <cstdio> 10 #include <ctime> 11 #include <map> 12 #include <bitset> 13 #include <cctype> 14 #define maxx INT_MAX 15 #define minn INT_MIN 16 #define inf 0x3f3f3f3f 17 #define mem(s,ch) memset(s,ch,sizeof(s)) 18 #define nc cout<<"nc"<<endl 19 const long long N=100; 20 using namespace std; 21 typedef long long LL; 22 int main() { 23 ios::sync_with_stdio(false);cin.tie(0); 24 int s,t1,t2,v1,v2; 25 cin>>s>>v1>>v2>>t1>>t2; 26 if((s*v1+2*t1)<(s*v2+2*t2)) cout<<"First"<<endl; 27 else if((s*v1+2*t1)==(s*v2+2*t2)) cout<<"Friendship"<<endl; 28 else cout<<"Second"<<endl; 29 return 0; 30 }
B. The number on the board
题目链接:http://codeforces.com/contest/835/problem/B
题目意思:给出一个自然数(这个自然数非常大,肯定爆long long,所以要用字符串读入),如果各位之和小于k,最少改动多少位才能使各位之和不小于k。如果已经大于等于k就输出0。
题目思路:运用贪心的思路。我们即可以把所有字符读进来,排序,然后从最小的字符开始把他们依次变成9,直到总和等于k为止,我们也可以采用分桶法(因为总共就只有9中字符),然后我们从0-9直接替换,就好了,其实也是一种排序的思路。只不过分桶法的复杂度是n,相对于快排的nlogn更加好而已。
代码:
1 //Author: xiaowuga 2 #include <iostream> 3 #include <algorithm> 4 #include <set> 5 #include <vector> 6 #include <queue> 7 #include <cmath> 8 #include <cstring> 9 #include <cstdio> 10 #include <ctime> 11 #include <map> 12 #include <bitset> 13 #include <cctype> 14 #define maxx INT_MAX 15 #define minn INT_MIN 16 #define inf 0x3f3f3f3f 17 #define mem(s,ch) memset(s,ch,sizeof(s)) 18 #define nc cout<<"nc"<<endl 19 const long long N=100; 20 using namespace std; 21 typedef long long LL; 22 int main() { 23 ios::sync_with_stdio(false);cin.tie(0); 24 int s,t1,t2,v1,v2; 25 cin>>s>>v1>>v2>>t1>>t2; 26 if((s*v1+2*t1)<(s*v2+2*t2)) cout<<"First"<<endl; 27 else if((s*v1+2*t1)==(s*v2+2*t2)) cout<<"Friendship"<<endl; 28 else cout<<"Second"<<endl; 29 return 0; 30 }
C. Star sky
题目链接:http://codeforces.com/contest/835/problem/C
题目意思:在一个100*100矩阵里面存在一些星星,每个星星都有自己的坐标和初始亮度,所有的星星都有一个最大亮度。每个星星达到最大亮度亮度以后就会变成0亮度(以此循环),现在给出一个范围,问这个范围内某个时间所有星星的亮度总和。注:边界上的也算范围内的。
题目思路:1 ≤ xi, yi ≤ 100, 0 ≤ si ≤ c ≤ 10,我们观察到题目给出的范围都很小,所以我们使用考虑使用一个三维数组d[x][y][c]表示(0,0),(x,0),(0,y),(x,y)四个点所围成的区域内所有初始亮度为c的数量。这样我们就可以通过容斥定理,得到任意一个范围内所有初始亮度为0-c的数量,根据时间取膜算出t时间亮度乘以数量,加在总和上,输出总和就可以了。好像有树状数组的做法,现在不会,不过这道题用这个方法已经可以AC了。
代码:
1 //Author: xiaowuga 2 #include <iostream> 3 #include <algorithm> 4 #include <set> 5 #include <vector> 6 #include <queue> 7 #include <cmath> 8 #include <cstring> 9 #include <cstdio> 10 #include <ctime> 11 #include <map> 12 #include <bitset> 13 #include <cctype> 14 #define maxx INT_MAX 15 #define minn INT_MIN 16 #define inf 0x3f3f3f3f 17 #define mem(s,ch) memset(s,ch,sizeof(s)) 18 #define nc cout<<"nc"<<endl 19 const long long N=105; 20 using namespace std; 21 typedef long long LL; 22 int dp[N][N][11]={0}; 23 int p[N][N]={0}; 24 int w[N][N]; 25 int main() { 26 ios::sync_with_stdio(false);cin.tie(0); 27 LL n,q,c; 28 cin>>n>>q>>c; 29 for(int i=0;i<n;i++){ 30 int x,y,z; 31 cin>>x>>y>>z; 32 dp[x][y][z]++; 33 } 34 for(int i=1;i<=100;i++) 35 for(int j=1;j<=100;j++){ 36 for(int k=0;k<=10;k++){ 37 dp[i][j][k]+=dp[i-1][j][k]+dp[i][j-1][k]-dp[i-1][j-1][k]; 38 } 39 } 40 LL t,x1,x2,y1,y2; 41 while(q--){ 42 cin>>t>>x1>>y1>>x2>>y2; 43 LL tot=0; 44 for(int i=0;i<=10;i++){ 45 int tmp=dp[x2][y2][i]-dp[x1-1][y2][i]-dp[x2][y1-1][i]+dp[x1-1][y1-1][i]; 46 if(i+t<=c) tot+=(i+t)*tmp; 47 else{ 48 LL x=t-(c-i+1); 49 tot+=(x%(c+1))*tmp; 50 } 51 } 52 cout<<tot<<endl; 53 54 } 55 return 0; 56 }
D. Palindromic characteristics
题目链接:http://codeforces.com/contest/835/problem/D
题目意思:定义一个k阶回文串,如果一个回文串,由左右连个回文串组成,那么他就是一个2阶回文串,如果其中一边(其中两边是一样的),又可以分解成两个回文串组成的回文串,那么他就是一个3届回文串,那么这个回文串既是1阶回文串,又是2阶回文串,还是一个三阶回文串,问整个字符串有多少个(1-len)阶回文串,输出一行。
思路:可以n^2先预处理一个二维的表来表示,下标i到下标j是否是一个回文串。然后对于每个回文串进行一次递归操作直到他的左右分成的两边不再是回文串,判断他对答案的贡献。
注:一个字符也是一个1阶回文串,所以答案的时候记得把ans[1]+len,回文串递归的时候注意奇数长度的回文串和偶数长度的回文串。分成两边是不同的。
代码:
1 //Author: xiaowuga 2 #include <iostream> 3 #include <algorithm> 4 #include <set> 5 #include <vector> 6 #include <queue> 7 #include <cmath> 8 #include <cstring> 9 #include <cstdio> 10 #include <ctime> 11 #include <map> 12 #include <bitset> 13 #include <cctype> 14 #define maxx INT_MAX 15 #define minn INT_MIN 16 #define inf 0x3f3f3f3f 17 #define mem(s,ch) memset(s,ch,sizeof(s)) 18 #define nc cout<<"nc"<<endl 19 const long long N=5000+5; 20 using namespace std; 21 typedef long long LL; 22 typedef int II; 23 II pd[N][N]={0}; 24 II ans[N]={0}; 25 II dfs(II l,II r){ 26 if(r-l<=0) return 1; 27 int t=1; 28 int x=r-l+1; 29 II y=(l+r)/2; 30 if(x%2){ 31 if(pd[l][y-1]&&pd[y+1][r]){ 32 t+=dfs(l,y-1); 33 } 34 } 35 else{ 36 if(pd[l][y]&&pd[y+1][r]){ 37 t+=dfs(l,y); 38 } 39 } 40 if(t!=1) ans[t]++; 41 return t; 42 43 } 44 II solve(II l,II r){ 45 int t=1; 46 int x=r-l+1; 47 II y=(l+r)/2; 48 if(x%2){ 49 if(pd[l][y-1]&&pd[y+1][r]){ 50 t+=dfs(l,y-1); 51 } 52 } 53 else{ 54 if(pd[l][y]&&pd[y+1][r]){ 55 t+=dfs(l,y); 56 } 57 } 58 return t; 59 } 60 int main() { 61 ios::sync_with_stdio(false);cin.tie(0); 62 char q[N]; 63 cin>>(q+1); 64 II len=strlen(q+1); 65 for(II i=1;i<=len;i++) pd[i][i]=1; 66 for(II i=1;i<=len;i++){ 67 for(II j=1;(i+j)<=len&&(i-j)>=1;j++){ 68 if(q[i+j]==q[i-j]) pd[i-j][i+j]=1; 69 else break; 70 } 71 for(II j=0;(i-j)>=1&&(i+j+1)<=len;j++){ 72 if(q[i-j]==q[i+j+1]) pd[i-j][i+j+1]=1; 73 else break; 74 } 75 } 76 for(II i=1;i<=len;i++) 77 for(II j=i+1;j<=len;j++){ 78 if(pd[i][j]){ 79 ans[1]++; 80 int t; 81 t=solve(i,j); 82 //cout<<i<<" "<<j<<" "<<t<<endl; 83 if(t!=1) ans[t]++; 84 } 85 } 86 ans[1]+=len; 87 for(II i=1;i<=len;i++){ 88 if(i==1) cout<<ans[i]; 89 else cout<<" "<<ans[i]; 90 } 91 cout<<endl; 92 return 0; 93 }