Codeforces Round #766 (Div. 2)补题记录+寒假计划
Codeforces Round #766 (Div. 2)补题记录+寒假计划
好久没有打cf,今天这场状态很差,只做出A和C两题,掉了53分。
B题
B题赛时过的人很多(7k+),但我是有思路很难写,赛后看题解才恍然大悟。
B是一个博弈问题 https://codeforces.com/contest/1627/problem/B
赛时我的想法是一个个模拟,但是发现很难写。
题解的思路是把坐在每个位置的ans都先算出来,再排序即为最终结果。
还有一个值得注意的点是给出数据组数t的范围,又给出n的总数不超过另一个范围,这时只用考虑n的总的范围。

#include<bits/stdc++.h> #define ll long long using namespace std; const int N = 100005; int n,t,m; int a[N]; int cnt; int r,c; int main(){ cin>>t; while(t--){ cnt=0; cin>>n>>m; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ int t1 = max(abs(i-1)+abs(j-1),abs(i-1)+abs(j-m)); int t2 = max(abs(i-n)+abs(j-1),abs(i-n)+abs(j-m)); a[++cnt]=max(t1,t2); } } sort(a+1,a+cnt+1); for(int i=1;i<=n*m;i++){ printf("%d ",a[i]); } puts(""); } return 0; }
D题
给你1e6个数,每个数的范围位于1到1e6之间,找出这些数两两之间有多少个不同的gcd。
(看到范围就知道这题的做法很可能是On或者Onlogn的)
思路如下:
对于每一个处于1到1e6范围内的数i,枚举它的倍数(i,2i,3i...),如果这些数中有一开始给定的,那么求出他们的gcd,如果这个gcd就等于i,则答案+1.

#include<bits/stdc++.h> #define ll long long using namespace std; const int N = 1000005; int n,t,m; int a[N]; bool vis[N]; int g[N]; int main(){ t=1; while(t--){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); vis[a[i]]=1; } int ans=0; for(int i=1;i<=1e6;i++){ if(vis[i]){ g[i]=i; continue; } for(int j=i*2;j<=1e6;j+=i){ if(vis[j]){ g[i]=__gcd(g[i],j); } } if(g[i]==i) ans+=1; } cout<<ans<<endl; } return 0; }
寒假计划
首先是多学一些算法,并踏踏实实做题。
cf上1650分。