Codeforces Round #674 (Div. 3)(A->D(前缀和出现次数))
A:http://codeforces.com/contest/1426/problem/A
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+50; int a[maxn]; int vis[maxn]; int main() { int T; scanf("%d",&T); while(T--) { int n,x; cin>>n>>x; if(n<=2) cout<<"1"<<endl; else { if(n<=x) cout<<"2"<<endl; else { int md=(n-2)/x; if((n-2)%x!=0) md++; cout<<md+1<<endl; } } } }
B:http://codeforces.com/contest/1426/problem/B
题意:
n种2*2的砖头,数量不限,是否能恰好铺满m*m的格子,砖块不可出界。
解析:
很明显,m奇数时一定不行。
只要存在一种砖块:左下角等于右上角即可。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=3e2+50; int a[maxn]; int vis[maxn]; struct node { int x,y; }st[maxn]; int mp[maxn][maxn]; int main() { int T; scanf("%d",&T); while(T--) { int n,m; cin>>n>>m; int ok=0,cnt=0; for(int i=1;i<=2*n;i+=2) { for(int j=1;j<=2;j++) { for(int c=1;c<=2;c++) cin>>mp[j][c]; } if(mp[1][1]==mp[2][2]&&mp[2][1]==mp[1][2]) { ok=1; } if(mp[1][2]==mp[2][1]) cnt++; } if(m%2) { cout<<"NO"<<endl; continue; } if(ok||cnt>=1) cout<<"YES"<<endl; else cout<<"NO"<<endl; } }
C:http://codeforces.com/contest/1426/problem/C
题意:
原始数组{1},可以对其某个数+1,或者复制一个。
使得总和>=n的最小操作数。
解析:
列了一会,发现很复杂,一个数可能来自于前面某个数的复制。
所以考虑这么一种方法:原始1自增到某个值x,然后一直复制自己d次,直到>=n
那么有x*d==n,如果让x+d最小,则x==d==sqrt(n)
所以枚举到根号n即可。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=3e5+50; const int inf=1e9; int a[maxn]; int b[maxn]; int d[maxn]; int main() { int t; cin>>t; while(t--) { ll n; cin>>n; ll minn=inf; for(int i=1;i*i<=n;i++) { ll md=(n-i)/i; if((n-i)%i!=0) md++; minn=min(minn,i-1+md); } cout<<minn<<endl; } }
D:http://codeforces.com/contest/1426/problem/D
题意:
可以在数组的任意位置插入一个无穷大/无穷小/0
使得不存在子数组和为0的最小操作数。
解析:
很容易想到前缀和。
如果sum[i]==sum[j],那么i+1~j这一段的和为0。
插入一个最大值,为了让操作数最小,放的时候跨度需要大一些。很明显,放到a[j]右边不合适,所以放到a[j]左边。
那么,由于最大值的存在,j之前的数,无论如何都不可能出现和为0。所以前面的就可以忽略,全新的前缀和记录从a[j]开始。map进行清0。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=2e5+50; const int inf=1e9; ll a[maxn]; int main() { ll n; cin>>n; ll sum=0; map<ll,bool>mp; mp[0]=true; int cnt=0; for(int i=1;i<=n;i++) { cin>>a[i]; sum+=a[i]; if(mp.count(sum)) { cnt++; sum=a[i]; mp.clear(); mp[0]=true; mp[sum]=true; } else { mp[sum]=true; } } cout<<cnt<<endl; }