A:http://codeforces.com/contest/1433/problem/A
解析:
直接手写个表,一个一个算就行了。
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn = 1e5 + 95; int num[9999]={0,1,11,111,1111,2,22,222,2222,3,33,333,3333,4,44,444,4444,5,55,555,5555,6,66,666,6666,7,77,777,7777, 8,88,888,8888,9,99,999,9999}; int main() { int t; cin>>t; while(t--) { int x; cin>>x; int cnt=0; for(int i=1;;i++) { if(i%4==1) cnt++; else if(i%4==2) cnt+=2; else if(i%4==3) cnt+=3; else cnt+=4; if(num[i]==x) { break; } } cout<<cnt<<endl; } }
B:http://codeforces.com/contest/1433/problem/B
题意:
对于[L,R]如果里面全是1,而且L-1是0或R+1是0,就可以整体左移或右移。
求使整个数组无0间隔的最小移动数。
解析:
先找到第一个1,从这里开始遍历
如果这一位是1,下一位是0,就往后找1,找到就加间距
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn = 1e5 + 95; int num[9999]={0,1,11,111,1111,2,22,222,2222,3,33,333,3333,4,44,444,4444,5,55,555,5555,6,66,666,6666,7,77,777,7777, 8,88,888,8888,9,99,999,9999}; int a[66]; int main() { int t; cin>>t; while(t--) { int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; int maxx=0; int ok=0; int id; for(int i=1;i<=n;i++) { if(a[i]==1) { id=i;break; } } int sum=0; for(int i=id;i<=n;i++) { if(a[i]==1&&a[i+1]==0) { int mdid; for(int j=i+2;j<=n;j++) { if(a[j]==1) { sum+=j-i-1; break; } } } } cout<<sum<<endl; } }
C:http://codeforces.com/contest/1433/problem/C
题意:
如果一个食人鱼,比左边或右边大,就可以吃掉左边或右边那条,自身+1
是否存在这么一条食人鱼,每次都让它吃,使得最后只剩它一条?
解析:
全相等肯定不存在。否则一定存在
先找出最大值,再遍历一次,如果存在某个值等于最大值,而且左边或右边鱼与它不相等,就输出它即可。
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn = 3e5 + 95; int num[9999]={0,1,11,111,1111,2,22,222,2222,3,33,333,3333,4,44,444,4444,5,55,555,5555,6,66,666,6666,7,77,777,7777, 8,88,888,8888,9,99,999,9999}; ll a[maxn]; int main() { int t; cin>>t; while(t--) { int n; cin>>n; cin>>a[1]; ll maxx=a[1]; int ok=0; for(int i=2;i<=n;i++) { cin>>a[i]; maxx=max(maxx,a[i]); if(a[i]!=a[i-1]) ok=1; } if(!ok) cout<<"-1"<<endl; else { int idx; a[n+1]=a[n]; for(int i=n;i>=1;i--) { if(a[i]==maxx&&(a[i]!=a[i-1]||a[i]!=a[i+1])) { idx=i; break; } } cout<<idx<<endl; } } }
D:http://codeforces.com/contest/1433/problem/D
题意:
n个组,ai表示其所属帮派。
用n-1条边,使得每个组之间可以互相到达。如果两个同帮派直接相连,那么就会发生冲突。
是否存在一种连接方式,避免这种情况?
解析:
1:全都属于一个帮派,肯定不存在。
2:想象成卫星图
找两个不相等的ai,连一起,其他的ai往它俩上连即可。
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn = 5e3 + 95; int num[9999]={0,1,11,111,1111,2,22,222,2222,3,33,333,3333,4,44,444,4444,5,55,555,5555,6,66,666,6666,7,77,777,7777, 8,88,888,8888,9,99,999,9999}; ll a[maxn]; bool ac1(int n) { } int main() { int t; cin>>t; while(t--) { int n; cin>>n; int ok=0; for(int i=1;i<=n;i++) { cin>>a[i]; } for(int i=2;i<=n;i++) { if(a[i]!=a[i-1]) { ok=1;break; } } if(!ok) cout<<"NO"<<endl; else { int id; for(int i=1;i<n;i++) { if(a[i]!=a[i+1]) { id=i; break; } } int idl=id,idr=id+1; cout<<"YES"<<endl; for(int i=1;i<=n;i++) { if(i==idl) continue; if(a[i]!=a[idl]) { cout<<i<<" "<<idl<<endl; } else if(a[i]!=a[idr]) { cout<<i<<" "<<idr<<endl; } } } } }
E:http://codeforces.com/contest/1433/problem/E
题意:
n个人,n为偶数
分成两组,每组围成一个圈跳舞,问一共有多少种组合方式。
注意:1,2 3,4 和 3,4 1,2是同样的分组方式
1,2,3,4和2,3,4,1是同一种跳舞排列方式。
解析:
首先,n个人中选两个,有C(n,n/2)种,/2即为分组种类数。
分完组,接下来看圈:
先把跳舞人看成线性,那么对于1,2,3,4 | 2, 3, 4, 1| 3, 4, 1, 2 。只要每个人的相对位置不变,那么这个1不管在什么位置,都是同一种排列方式。
所以对于一种排列方式,需要固定一个参照点,这个点不要动,其他的随意放即可。
对于一个圈,n/2个人,先固定一个参照点,那么还剩n/2-1个人,所以有(n/2-1)! 种排列方式,而另一个圈还有 (n/2-1)! 种
所以总的答案就是:C(n,n/2) * (n/2-1)! (n/2-1)! / 2
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn = 1e5 + 95; const int inf=999999999; int main() { ll n; cin>>n; ll sum=1; ll md=n; for(int i=1;i<=n/2;i++) { sum*=md; md--; } md=1; for(int i=1;i<=n/2;i++) { md*=i; } sum=sum/md; md=1; for(int i=1;i<=n/2-1;i++) { md*=i; } cout<<sum*md*md/2<<endl; }