A Live Love
水

#include <algorithm> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const int maxn = 1e5 + 1; int main() { int t; scanf("%d", &t); while(t--) { int n,m; scanf("%d%d",&n,&m); if(m==0){ printf("0 0\n"); continue; } if(n==m){ printf("%d %d\n",n,m); continue; } if(n>=2*m-1){ printf("%d %d\n",m,1); continue; } for(int i=2;i<=m;i++) { if (n - m >= (m / i + (m % i != 0)) - 1) { printf("%d %d\n", m, i); break; } } } return 0; }
B Red Black Tree
留坑
C Halting Problem
題意:自定義了一些程序,然后問程序會不會崩潰,也就是會不會有死循環出現
思路:隊友寫的,大致就是同一步不可以運行一摸一樣的兩次吧

#include <algorithm> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const int maxn = 1e5 + 1; struct com{ char cm[4]; int v,k; }prog[10007]; bool vstd[256][10007]; int main() { int n,t; scanf("%d", &t); while(t--) { scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%s%d",prog[i].cm,&prog[i].v); if(prog[i].cm[0]!='a'){ scanf("%d",&prog[i].k); } } int r=0,ins=1; int flag=1; memset(vstd,0,sizeof(vstd)); while(true){ if(ins>n){ break; } if(vstd[r][ins]){ flag=0; break; } switch(prog[ins].cm[1]){ case 'd'://+ vstd[r][ins]=1; r+=prog[ins].v; r%=256; ins++; break; case 'e'://== vstd[r][ins]=1; if(r==prog[ins].v){ ins=prog[ins].k; }else{ ins++; } break; case 'n'://!= vstd[r][ins]=1; if(r!=prog[ins].v){ ins=prog[ins].k; }else{ ins++; } break; case 'l'://< vstd[r][ins]=1; if(r<prog[ins].v){ ins=prog[ins].k; }else{ ins++; } break; case 'g'://> vstd[r][ins]=1; if(r>prog[ins].v){ ins=prog[ins].k; }else{ ins++; } break; default: vstd[r][ins]=1; ins++; break; } } if(flag){ puts("Yes"); }else{ puts("No"); } } return 0; }
D Pixel Art
留坑
E Infinite Parenthesis Sequence
留坑
F Chaleur
留坑
G Couleur
留坑
H Traveling on the Axis
題意:模擬紅綠燈,1過,0停,每一秒之后都會改變所有的燈的狀態,1變0,0變1
思路:只需要特判第一步走的需不需要停就可以,之后走起來之后的狀態都是重復進行的

#include <algorithm> #include<cstdio> #include<iostream> #include<cstring> using namespace std; typedef long long ll; char rd[112345]; ll len; int main() { int n,t; while(~scanf("%d",&t)) { while (t--) { scanf("%s", rd); len = strlen(rd); long long ans = 0; long long tmp; for (ll i = 0; i < len - 1; i++) { tmp = (len - i - 1) * (i + 1); if (rd[i] == rd[i + 1])tmp *= 2; ans += tmp; } //ll b=0; for (ll i = 0; i < len; i++) { ans += rd[i] == '1' ? (len - i) : (len - i) * 2; //b+=rd[i]=='1'?(len-i):(len-i)*2; } cout << ans << endl; } } return 0; }
I Kuririn MIRACLE
留坑
J Press the Button
題意:按燈,當燈亮的時候按壓可以加分,每一次按都會重置燈的熄滅時間。
思路:可以先找到兩個數的最小公倍數,然后就可以按照這個周期進行一些剪枝,在每一次周期或者是最后一次的剩余時間里可以模擬,隊友用了棧寫之后超時了,后來另一位隊友沒有用棧就AC了

#include <algorithm> #include<cstdio> #include<iostream> #include<cstring> using namespace std; typedef long long ll; ll gcd(ll x, ll y) { return x % y == 0 ? y : gcd(y, x % y); } int main() { int t; while(~scanf("%d",&t)) { while (t--) { ll a,b,c,d,v,t; scanf("%lld%lld%lld%lld%lld%lld",&a,&b,&c,&d,&v,&t); ll time=0; ll tt=a*c/gcd(a,c); ll ta=a,tc=c; ll tans=0; while(ta<=tt || tc<=tt){ if(ta<=tc){ tans+=b; if(ta-time>v){ tans--; } time=ta; ta+=a; }else if(ta>tc){ tans+=d; if(tc-time>v){ tans--; } time=tc; tc+=c; } } ll sans=0;ta=a,tc=c; time=0; ll res=t%tt; while(ta<=res|| tc<=res){ if(ta<=tc){ sans+=b; if(ta-time>v){ sans--; } time=ta; ta+=a; }else if(ta>tc){ sans+=d; if(tc-time>v){ sans--; } time=tc; tc+=c; } }sans+=b+d-1; cout<<tans*(t/tt)+sans<<endl; } } return 0; }
K XOR Clique
題意:找一個最大的集合,使得這些任意兩個異或后的值都比最小的那個小
思路:有個隊友說可以用字典樹,后來我想了想好像只需要計算每一個2,4,8,16,32,64,128,256,512,1024......這些區間的數字的個數就可以了,因為不同的這些2的次方它們異或之后顯然最高位會是1,使得它們肯定會比最小的那個大,所以肯定是在同一個集合里面的,同一個集合里面的它們的第一位是相同的,所以異或之后肯定會比最小的那個數要小,所以統計區間個數就可以了,先打個表記錄一下2的次方。

#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<cstdlib> #include<queue> #include<set> #include<stack> #include<vector> #include<map> #include<ctime> using namespace std; using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const int maxn = 1e5 + 1; int main() { ll a[40]; int sum[40]; for(ll i=1;i<=30;i++) { a[i]=(ll)pow(2*1.0,i); // cout<<a[i]<<" "; } int t; while(~scanf("%d",&t)) { while(t--) { int n; scanf("%d",&n); memset(sum,0,sizeof sum); for(int i=0;i<n;i++) { int x; scanf("%d",&x); for(int num=1;num<=30;num++) { if(x<a[num]) { sum[num]++; break; }else continue; } } int maxx=-1; for(int i=1;i<=30;i++) maxx=max(maxx,sum[i]); printf("%d\n",maxx); } } }