标签:double string 个数 构造 iostream for 排序 lap shiro
https://vjudge.net/contest/354199#overview
A:
简单模拟。
#include<bits/stdc++.h> using namespace std; int n,ans; bool vis[29]; string S; map<string,bool>ma; char s[3001]; int num[29]; void solve(){ cin >> n; for(int i = 1;i <= n;i ++){ scanf("%s",s); memset(vis,0,sizeof(vis)); int len = strlen(s),tot = 0; S.clear(); for(int i = 0;i < len;i ++){ if(vis[s[i] - ‘a‘]) continue; num[tot ++] = s[i]; vis[s[i] - ‘a‘] = 1; } sort(num,num + tot); for(int i = 0;i < tot;i ++) S += (char)(num[i] + ‘a‘); if(!ma[S]) ans ++,ma[S] = 1; } cout << ans; return; } int main(){ solve(); return 0; }
B:
题目大意是有14个孔里装着奇数或0个小球,将其中一个孔的小球全部取出依次一个个地放入后面的孔(第14个孔的下一个是第1个孔),不断循环,直到放完。只取一次,最大化有偶数个球的孔的总球数。
简单模拟。。。。
题目理解有偏差,导致WA了5次,某个孔的球取出后,这个孔的球数自然为0.。。。。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll MAXN = 21; ll num[MAXN],a[MAXN]; void solve(){ ll ans = 0; for(ll i = 1;i <= 14;i ++) scanf("%lld",&num[i]); for(ll i = 1;i <= 14;i ++){ if(num[i]){ for(ll j = 1;j <= 14;j ++) a[j] = num[j]; a[i] = 0; for(ll j = 1;j <= 14;j ++) a[j] += num[i] / 14; ll x = num[i] % 14,f = i; for(int j = i + 1;j <= 14 && x;j ++) x -- ,a[j] ++; for(int j = 1;j <= x;j ++) a[j] ++; ll cnt = 0; for(ll j = 1;j <= 14;j ++) if(a[j] % 2 == 0) cnt += a[j]; ans = max(ans,cnt); } } cout << ans; return; } int main(){ solve(); return 0; }
C:
二分
注意某个回合所有战士死亡后,在这一回合立刻复活,且这一回合剩下的箭失效。(WA了一次)
本质就是两个前缀和比较大小,用二分即可。
#include<iostream> #include<algorithm> using namespace std; const int MAXN = 200001 + 99; typedef long long ll; ll k[MAXN],sum[MAXN]; ll n,q,x; int main(){ cin >> n >> q; for(int i = 1;i <= n;i ++) scanf("%lld",&x),sum[i] = x + sum[i - 1]; for(int i = 1;i <= q;i ++){ scanf("%lld",&k[i]); if(k[i] + k[i - 1] >= sum[n]) k[i] = 0; else k[i] += k[i - 1]; ll pos = upper_bound(sum + 1,sum + n + 1,k[i]) - sum; printf("%lld\n",n - pos + 1); } return 0; }
抓住本质就很好写了。
D:
简单模拟
对于奇数块,老老实实一刀刀切。
对于偶数块,一刀可以切两块。
注意1块的情况,即不切。(WA了一次)
#include<iostream> using namespace std; int main(){ long long n; cin >> n; if(n == 0){ cout << 0 << endl; return 0; } if((n + 1) % 2) cout << n + 1; else cout << (n + 1) / 2; return 0; }
E:
模拟
简化一下题意:有三个字符串,找出beauty最高的字符串。有n次操作,每次操作将任意字母替换为其他字母。
beauty值是字符串中同一字母出现的最大次数。
记原始串同一字母出现最大次数为Max,贪心的思想,其他字母尽量转化成此字母。
两种情况:
1、Max + n <= len ans = Max + n
2、Max + n > len ans = len;
WA。。。。
考虑对于一个字母,如果对其操作数超过两次,那么它可以转化为任意一个字母(包括它自身),因此情况2一定成立。
但是对于情况1,如果Max = len,即aaaaaaa,n = 1,那么a只能变成其他字母,ans = len - 1。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; char s[400001]; int num[222]; int cnt[4],pos,n,ans; void solve(){ cin >> n; for(int i = 1;i <= 3;i ++){ int Max = -1; memset(num,0,sizeof(num)); scanf("%s",s); int len = strlen(s); for(int i = 0;i < len;i ++){ num[s[i]] ++; Max = max(num[s[i]],Max); } if(Max == len && n == 1) cnt[i] = len - 1; else if(Max + n <= len) cnt[i] = Max + n; else if(Max + n > len) cnt[i] = len; if(ans < cnt[i]){ ans = cnt[i]; pos = i; } } for(int i = 1;i <= 3;i ++){ if(cnt[i] == ans && i != pos){ cout << "Draw"; return; } } if(pos == 1) cout << "Kuro"; else if(pos == 2) cout << "Shiro"; else cout <<"Katie"; return; } int main(){ solve(); return 0; }
F:
G:
简单模拟
由于是环,间隔数和珍珠数相同,如果链数可均分到每个间隔,则符合。
考虑到珍珠数可能为0,不能做模数,需要特判。。。。。(WA一次)。
#include<iostream> #include<cstring> #include<algorithm> using namespace std; char s[201]; int n1,n2; int main(){ scanf("%s",s); int len = strlen(s); for(int i = 0;i < len;i ++){ if(s[i] == ‘-‘) n1 ++; else n2 ++; } if(!n1 || !n2 || n1 % n2 == 0) cout << "YES"; else cout << "NO"; return 0; }
H:
构造
在4 * n的图放k个#(障碍),使得左上角到右下角和左下角到右上角最短路径数量相同。
如果k是偶数,显然让图上下对称即可。
如果k是奇数,那么转化一下,从左上角到右下角就等价于从右下角出发到左上角,#放置后,图左右对称即可。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,k; char ma[1001][1001]; void solve(){ cin >> n >> k; for(int i = 1;i <= 4;i ++) for(int j = 1;j <= n;j ++) ma[i][j] = ‘.‘; if(k % 2 == 0) for(int i = 2;i <= n - 1 && k;i ++,k -= 2) ma[2][i] = ma[3][i] = ‘#‘; else { int pos = n / 2 + 1; ma[2][pos] = ‘#‘; int cnt = k / 2; for(int i = pos - 1;i >= 2 && cnt;i --) ma[2][i] = ‘#‘,cnt --; cnt = k / 2; for(int i = pos + 1;i <= n - 1 && cnt;i ++) ma[2][i] = ‘#‘,cnt --; if(cnt){ int t = cnt; for(int i = pos - 1;i >= 2 && t;i --) ma[3][i] = ‘#‘,t --; t = cnt; for(int i = pos + 1;i <= n - 1 && t;i ++) ma[3][i] = ‘#‘,t --; } } cout << "YES" << endl; for(int i = 1;i <= 4;i ++){ for(int j = 1;j <= n;j ++){ cout << ma[i][j]; } cout << endl; } } int main(){ solve(); return 0; }
I:
J:
数论?
从$\sqrt{n}$枚举到1,判断即可。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; typedef long long ll; ll n; ll calc(ll a){ ll num = 0; while(a) num ++,a /= 10; return num; } void solve(){ cin >> n; for(ll i = sqrt(n);i >= 1;i --){ if(n % i == 0){ cout << max(calc(i),calc(n / i)) << endl; return; } } return; } int main(){ solve(); return 0; }
K:
数学
首先从大到小排序,则前A个数可以取到最大平均值。
两种情况讨论:
cnt[a[i]] : 第i个数出现的次数。
1、前A个数相同(均为最大的数),令$t = min\left ( cnt[a[A]] ,B\right )$,答案为$\sum_{i = A}^{t}C_{cnt[a[A]]}^{i}$
2、前A个数不同,记count为前A个数a[A]出现的次数。答案为$C_{cnt[a[A]]}^{count}$
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> using namespace std; typedef long long ll; const ll MAXN = 1001; ll sum[MAXN],a[MAXN]; ll n,A,B; ll dp[MAXN][MAXN]; map<ll,ll>ma; void C(){ dp[1][1] = 1; for(ll i = 0;i <= 151;i ++) dp[i][0] = 1; for(ll i = 2;i <= 151;i ++) for(ll j = 1;j <= 151;j ++) dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1]; } bool cmp(ll a,ll b){ return a > b; } void solve(){ C(); cin >> n >> A >> B; for(ll i = 1;i <= n;i ++) scanf("%lld",&a[i]),ma[a[i]] ++; sort(a + 1,a + n + 1,cmp); ll sum = 0; double pingjun = 0.0; for(ll i = 1;i <= A;i ++) sum += a[i]; pingjun = (double)sum / (double)A; ll pos = 0; for(ll i = A;i >= 1;i --){ if(a[i] != a[i - 1]){ pos = i; break; } } ll ans = 0; if(pos == 1) for(int i = A;i <= B;i ++) ans += dp[ma[a[A]]][i]; else ans = dp[ma[a[A]]][A - pos + 1]; printf("%.8lf\n",pingjun); printf("%lld\n",ans); return; } int main(){ solve(); return 0; }
L:
贪心
让奇数和4的倍数相邻即可。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,f1,f2,f3; void solve(){ int x; cin >> n; for(int i = 1;i <= n;i ++){ scanf("%d",&x); if(x % 4 == 0) f1 ++; else if(x % 2 == 0) f2 ++; else f3 ++; } if(!f2 && f3 == f1 + 1) cout << "Yes" << "\n"; else if(f1 >= f3) cout << "Yes" << endl; else cout << "No" << endl; } int main(){ solve(); return 0; }
M:
模拟
S型放置数字即可。
例如:
5 5 5 5 5
5 4 4 4 4
2 3 3 3 4
2 2 2 1 1
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 1204; int h,w,n; int ma[MAXN][MAXN],a[20001]; void solve(){ cin >> h >> w >> n; for(int i = 1;i <= n;i ++) cin >> a[i]; int tot = n; for(int i = 1;i <= h;i ++){ if(i % 2){ for(int j = 1;j <= w;j ++){ ma[i][j] = tot,a[tot] --; if(a[tot] == 0) tot --; } } else{ for(int j = w;j >= 1;j --){ ma[i][j] = tot,a[tot] --; if(a[tot] == 0) tot --; } } } for(int i = 1;i <= h;i ++){ for(int j = 1;j <= w;j ++){ cout << ma[i][j] << " "; } cout << endl; } return; } int main(){ solve(); return 0; }
标签:double string 个数 构造 iostream for 排序 lap shiro
原文地址:https://www.cnblogs.com/cgold/p/12242336.html