Codeforces Round #671 (Div. 2)(A->D2(構造))
A:http://codeforces.com/contest/1419/problem/A
解析:
稀裡糊塗過得,不想說了。。。
#include <bits/stdc++.h> #include<vector> using namespace std; typedef long long ll; const int maxn = 1e5+10; vector<int>g[maxn]; int si[maxn]; int ok = 0 ; int x,y; int main(){ int t; cin >> t; while(t--) {int n; cin>>n; char s[1005]; scanf("%s",s+1); int c1=0,c2=0,c3=0,c4=0; int vis[1005]; if(n==1) { if((s[1]-'0')%2) { cout<<"1"<<endl; } else cout<<"2"<<endl; continue; } for(int i=1;i<=n;i++) { if(i%2&&(s[i]-'0')%2==0) { c1++; } if(i%2==0&&(s[i]-'0')%2!=0) { c2++; } } if(n%2) { if(c1<(n/2+1)) cout<<"1"<<endl; else cout<<"2"<<endl; } else { if(c2<(n/2)) cout<<"2"<<endl; else cout<<"1"<<endl; } } }
B:http://codeforces.com/contest/1419/problem/B
題意:
給我讀懵了。。。
意思就是,n階臺階,它的階數是1~n。
如果其還含有n個不相交的正方形,即為nice
給出x個方塊,能組成多少個nice?
解析:
列了一下,發現第i個nice其階數為:2^i-1
根據樣例,nice最多30個。
所以把前30個nice的階數列出來,根據等差數列求出每一階所需方塊數,存起來。
對給出的x,從小到大累加方塊數即可。
#include<bits/stdc++.h> #include<cmath> #define pb push_back using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn=1e5+10; const int mod=1e9+7; const ll inf=0x3f3f3f3f3f3f3f3f; const double eps=1e-14; ll a[50],b[maxn]; ll tot=0; void init() { ll sum=1,x=1; for(int i=1;i<=30;i++) { ll md=pow(2,i)-1; ll md2=(md*md+md)/2; a[tot++]=md2; } } int main() { int t; cin>>t; init(); while(t--) { ll n; cin>>n; ll sum=0; int cnt=0; for(int i=0;i<tot;i++) { sum+=a[i]; if(sum<=n) cnt++; else break; } cout<<cnt<<endl; } }
C:http://codeforces.com/contest/1419/problem/C
題意:
初始被感染的rating為x,除他之外還有n個初始rating。
每次比賽可以對任意rating進行+-操作,但是總變化數為0。
感染條件:rating與x相同,每次感染髮生在每次比賽前和後。
求最少比賽數,以感染所有rating
解析:
1:所有rating都為x,需要0次
2:sum==n*x,此時一次比賽,即可把所有數字變成x,需要1次
3:x在n個初始rating中出現,假設定為id,初始id被感染,然後把除id之外所有非x的rating全變為x,需要補的全安排在id頭上(因為總變化數為0),即可感染所有人,需要1次。
4:初始x沒有出現,那麼第一步,把n-1個全變為x,需要補的放在最後那個頭上,n-1個全被感染。第二步,最後那個變為x即可。總共兩步。
#include<bits/stdc++.h> #include<cmath> #include<map> #define pb push_back using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn=1e3+10; const int mod=1e9+7; const ll inf=0x3f3f3f3f3f3f3f3f; const double eps=1e-14; int a[maxn]; ll tot=0; int main() { int t; cin>>t; while(t--) { int n,x; int cnt=0; cin>>n>>x; int ok1=0,ok2=0; int sum = 0 ; for(int i=1;i<=n;i++) { cin>>a[i]; sum+=a[i]; if(a[i]!=x) ok1=1; else ok2=1; } if(!ok1) { cout<<"0"<<endl; } else if(sum==x*n||ok2) cout<<"1"<<endl; else cout<<"2"<<endl; } }
D1:http://codeforces.com/contest/1419/problem/D1
D2:http://codeforces.com/contest/1419/problem/D2
題意:
當一個商品小於左邊和右邊的價格,我們就能購買它,問如何排列商品能讓我們能買的最多
D1價格各不相等,D2可相等。
解析:
比賽時D1直接想的是,既然是小於兩邊,那麼小的肯定不能連著排
所以先對價格排序,從小到大放,先從偶數位開始放,然後餘下的按奇數位放。
D1過了以後就下了,沒想到,這套程式碼同樣能過D2,改都不用改,血虧。。。。
#include <bits/stdc++.h> #include<vector> using namespace std; typedef long long ll; const int maxn = 1e5+10; vector<int>g[maxn]; int a[maxn]; int b[maxn]; int vis[maxn]; int ok = 0 ; int x,y; int main(){ int n; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; b[i]=0; vis[i]=0; } sort(a+1,a+1+n); int tot=1; for(int i=2;i<=n;i+=2) { b[i]=a[tot]; vis[tot]=1; tot++; } int cnt=0; tot=1; for(int i=1;i<=n;i++) { if(!vis[i]) { b[tot]=a[i]; tot+=2; } } int c=0; for(int i=2;i<n;i++) { if(b[i]<b[i-1]&&b[i]<b[i+1]) c++; } cout<<c<<endl; for(int i=1;i<=n;i++) cout<<b[i]<<" "; cout<<endl; }