Codeforces Round #615 (Div. 3) 补题记录
第一次搞CF,结果惨不忍睹...还是太菜了
A:要用到全部的钱,所以总数必须是3的倍数,而且初始状态下任意一人的钱数不能超过总数除以3,否则没法分了
(也就这个签到算是在我能力范围之内了....)
1 #include <iostream> 2 #include <cmath> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 #include <map> 7 using namespace std; 8 int main () 9 { 10 int t,a,b,c,m; 11 cin>>t; 12 while (t--) 13 { 14 int flag=0; 15 scanf("%d %d %d %d",&a,&b,&c,&m); 16 int all=a+b+c+m; 17 if (all%3==0&&a<=all/3&&b<=all/3&&c<=all/3) 18 cout<<"YES"<<endl; 19 else 20 cout<<"NO"<<endl; 21 22 } 23 return 0; 24 }
B:一看到图马上怂了...还有字典序,我蒟蒻立刻放弃了....(其实真正好好看的话也就那样...)
最开始看到的话,毕竟只能在右,上两个方向走,所以如果有两个点他们的斜率是负的(一个在左上一个在右下)明显就不行(而且这时间复杂度n^2就很诡异)
但是我没法找出一条路线,看了题解之后,满足字典序最小的话就是先R再U
后面看了题解知道可以用一次结构体排序来确定下一次该去的位置,而且排序后只需要比较相邻的两个点是否符合题意就行
cmp排序函数
bool cmp (node a, node b) { if (a.y!=b.y) return a.y<b.y; else return a.x<b.x; }
sort完之后,就是从最下面一行逐渐向上,在一行之内从左到右的顺序排(如表格),所以可能出现不符题意的情况只存在与一行的末尾和上一行的开头这两个点。
7 | 8 | 9 |
4 | 5 | 6 |
1 | 2 | 3 |
因为是排好序的,所有从(0,0)开始遍历到最后一个点就行了
#include <iostream> #include <algorithm> using namespace std; struct node { int x,y; }p[1010]; bool cmp (node a, node b) { if (a.y!=b.y) return a.y<b.y; else return a.x<b.x; } int main() { int t,n; scanf("%d",&t); while (t--) { int flag=1; scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d %d",&p[i].x,&p[i].y); p[0].x=0,p[0].y=0; sort(p+1,p+n+1,cmp); for (int i=1;i<=n;i++) { if ((p[i].x<p[i-1].x)&&(p[i].y>p[i-1].y)) flag=0; } if (flag==0) printf("NO\n"); else { printf("YES\n"); for (int i=1;i<=n;i++) { for (int j=0;j<(p[i].x-p[i-1].x);j++) printf("R"); for (int j=0;j<(p[i].y-p[i-1].y);j++) printf("U"); } printf("\n"); } } return 0; }
C :这题就很诡异,我本来觉得就不可能过的居然就过了...
题意就是给一个数,把它分解为三个大于2的数相乘的形式,个人想法就是从2开始遍历,找到一个因数就先除掉,再做一遍,找到下一个不与上一个数重合的因数除掉,这样就剩三个数,最后比较一下三个数里有没有相等的,没有就输出。总觉得有什么问题,但是先把代码记一下吧。
#include <iostream> #include <cmath> #include <algorithm> #include <cstdio> #include <cstring> #include <map> using namespace std; int main () { int t,n; scanf("%d",&t); while (t--) { int num[2]={0},flag=0; scanf("%d",&n); for (int i=2;i<=sqrt(n*1.0);i++) { if(n%i==0&&flag==0) { num[0]=i; n=n/i; i=1; flag++; } else if (n%i==0&&flag==1&&i!=num[0]) { num[1]=i; n=n/i; flag=2; break; } } if (flag==2&&(num[0]!=n)&&(num[1]!=n)) printf("YES\n%d %d %d\n",num[0],num[1],n); else printf("NO\n"); } return 0; }
D:看不懂题还行....
题意:MEX是一个数组中没有出现过的最小非负整数,第一行给定q和x,随后的q行都给一个数,对于这个数,可以任意增加或减少任意个x,再加入到数组中,要求q次加完之后使MEX最大。