codeforces 706 div2题解
A Split it!
思路:
翻轉后看前k個連續是否相等,并且滿足k?2+1<=nk*2+1 <= nk?2+1<=n
代碼:
#include<bits/stdc++.h> #include<iostream> #include <stdio.h> using namespace std; const int maxn=200005; const int base=131; typedef long long ll; #define pi acos(-1) #define INF 0x3f3f3f3f #define mod 998244353 const int inf=1<<30; int a[maxn]; int b[maxn]; vector<int> pos; int main() {//freopen("data.in","r",stdin);//freopen("1.out","w",stdout);int t,n,k;cin>>t;string s,s1;while(t--){cin>>n>>k;cin>>s;s1 = s;reverse(s.begin(),s.end());//cout<<s<<endl;int f = 0,cnt = 0;for(int i = 0;i < n ; i++ ){if(s[i] != s1[i] ){if(cnt >= k)f = 1;break;}cnt++;if(cnt >= k){f = 1;break;}}if(k == 0 || ( f && (k*2+1 <= n)))cout<<"YES"<<endl;elsecout<<"NO"<<endl;}return 0; }B Max and Mex
思路:可以用a+b+12\frac{a+b+1}{2}2a+b+1?計算
如果加入的這個b已經存在于序列中,mex和max不會變,答案為原序列中不同元素個數。
如果b不存在于序列中,并且原序列不是連續的,則有mex<maxmex < maxmex<max,那么b最小為mex+mex+1+12\frac{mex +mex+1+1}{2}2mex+mex+1+1?,即mex+1mex+1mex+1,加入后b后mex′mex'mex′和max′max'max′不變,答案為原序列中不同元素個數加一。
如果b不存在于序列中,并且原序列是連續的則有mex>maxmex > maxmex>max,,mex一定為max+1max+1max+1,那么b為max+max+1+12\frac{max +max+1+1}{2}2max+max+1+1?,即max+1max+1max+1。
加入后b后,mex′mex'mex′變為mex+1=max+2mex+1= max +2mex+1=max+2 ,max′max'max′變為max+1max+1max+1,新的b′=b+1=max+2b'=b+1=max+2b′=b+1=max+2,以此類推……答案為原序列中不同元素個數加k。
代碼:
#include<bits/stdc++.h> #include<iostream> #include <stdio.h> using namespace std; const int maxn=200005; const int base=131; typedef long long ll; #define pi acos(-1) #define INF 0x3f3f3f3f #define mod 998244353 const int inf=1<<30; ll a[maxn]; set<ll> vis; int main() {//freopen("data.in","r",stdin);//freopen("1.out","w",stdout);ll t,n,k;cin>>t;string s,s1;while(t--){cin>>n>>k;vis.clear();memset(a,0,sizeof(a));for(ll i = 1;i <= n;i++){cin>>a[i];vis.insert(a[i]);}sort(a+1,a+1+n);ll aa,bb;bb = a[n];ll cnt = 0;if(k == 0){cout<<vis.size()<<endl; continue;}ll i ;for( i =1 ;i <= n;i++){if(i == 1 && a[i] != 0){aa = 0;break;}if(a[i+1] != a[i]+1 ){aa = a[i]+1;break;}}ll b = (aa + bb +1) / 2;cnt++;if(vis.find(b) != vis.end() || cnt == k){vis.insert(b);cout<<vis.size()<<endl; }else{ //找不到if(aa > bb)cout<<vis.size() + k<<endl;elsecout<<vis.size() + 1<<endl;}}return 0; }C Diamond Miner
思路:
將所有的x和y都映射到第一象限上,依次將最小的x點和y點一一對應求距離即可。
代碼:
#include<bits/stdc++.h> #include<iostream> #include <stdio.h> using namespace std; const int maxn=200005; const int base=131; typedef long long ll; #define pi acos(-1) #define INF 0x3f3f3f3f #define mod 998244353 const int inf=1<<30; ll a[maxn],b[maxn]; int main() {//freopen("data.in","r",stdin);//freopen("1.out","w",stdout);ll t,n,k;cin>>t;while(t--){cin>>n;ll x ,y;int cnt1 = 0,cnt2 = 0; for(int i = 1;i <= n *2;i++){cin>>x>>y;if(x == 0){if(y > 0)a[++cnt1] = y;else a[++cnt1] = -y;}if(y == 0){if(x > 0)b[++cnt2] = x;else b[++cnt2] = -x;}}sort(b+1,b+n+1);sort(a+1,a+n+1);double ans = 0.0;for(int i =1;i <= n; i++){ans += sqrt(a[i] * a[i]*1.0 + b[i] *b[i]*1.0);}printf("%.15lf\n",ans);}return 0; }D Let’s Go Hiking
題意:給定一個序列,Qingshan只能沿著單調下降的方向移動,Daniel只能沿著單調上升的方向移動,Q先移動,D后手,誰先不能移動誰輸。
思路:
首先在這個n長的序列中可能有m個單調的連續子序列。Q和D都只能在單調子序列上移動,Q選擇序列中最大的位置,D選擇最小的位置。
為了讓自己的移動步數多,Q和D都會選擇最長的單調序列,因為如果讓出最長的序列則必輸。如果只有一個最長的單調序列,Q和D相當于往對方移動,必會相遇。由于Q先手,Q必輸。
有多條等長的間隔開的單調序列,Q和D能移動的距離相等,因為Q先手,Q必輸。
有連接在一起的等長單調序列時,即一個波形,單調上升和單調下降的部分長度相等為L。如果長度L為偶數,和上面的情況相同,Q必輸。
如果每部分長度L為奇數,Q先手,Q可以往往兩個方向移動。長度為奇數下Q和D相遇,Q先手D必輸,所以D只能放在第二小的位置將這種相遇轉化為長度為偶數的相遇;但是Q可以選擇向另一邊移動,Q和D同方向移動,Q還是可以L次,D放在第二小的位置只能移動L-1次,D必輸。
代碼:
#include<bits/stdc++.h> #include<iostream> #include <stdio.h> using namespace std; const int maxn=200005; const int base=131; typedef long long ll; #define pi acos(-1) #define INF 0x3f3f3f3f #define mod 998244353 const int inf=1<<30; int p[maxn]; int l[maxn],r[maxn];int main() {//freopen("data.in","r",stdin);//freopen("1.out","w",stdout);int n;cin>>n;for(int i = 1; i <= n;i++){cin>>p[i];}l[1] = 1;r[n] = 1;for(int i =2 ;i <= n;i++)l[i] = (p[i] > p[i-1])? l[i-1] + 1 : 1;for(int i = n-1 ;i >= 1; i--)r[i] = (p[i] > p[i+1]) ? r[i+1] + 1 : 1;int ma = 0,cnt = 0,vis = 0;for(int i = 1;i <= n;i++){if(l[i] > ma || r[i] > ma){ma = max(l[i],r[i]);cnt = 1;vis = i;}else if(l[i] == ma || r[i] == ma){cnt = 0;}}int ans;int mx = l[vis] > r[vis]? l[vis] : r[vis];int mi = l[vis] > r[vis]? r[vis] : l[vis];if(cnt && mx % 2 &&mx == mi)ans = 1;elseans = 0;cout<<ans<<endl;return 0; }E Garden of the Sun
題意:
n行m列的農田里,種了n*m朵太陽花,因陽光猛烈太陽花死掉了許多,剩下的空格子沒有共同邊或角。
你需要移除剩下的太陽花,使得滿足:一、空格是聯通的,二、任何兩個空格間都有一條簡單路徑,即所有的空格是不成環的。
思路:
構造,構的我心態炸了,就硬構。
每三行把其中一行全置空,行是三的倍數就置空中間的,不是置空第一行,然后聯通剩下兩行就可以了。
代碼:
#include<bits/stdc++.h> #include<iostream> #include <stdio.h> using namespace std; const int maxn=60005; const int base=131; typedef long long ll; #define pi acos(-1) #define INF 0x3f3f3f3f #define mod 998244353 const int inf=1<<30; string g[maxn]; string ans[maxn];int main() {//freopen("data.in","r",stdin);//freopen("1.out","w",stdout);// ios::sync_with_stdio(false); cin.tie(0);int t,n,m;cin>>t;while(t--){cin>>n>>m;for(int i = 0; i < n; i++){g[i].clear();cin>>g[i];}for(int i = (n%3) == 0; i < n;){for(int j = 0; j < m; j++)g[i][j] = 'X';i += 3;if(i >= n)break;int pos = 1;if(m == 1 || (g[i - 1][1] != 'X' && g[i - 2][1] != 'X' )){pos = 0;}g[i - 1][pos] = 'X';g[i - 2][pos] = 'X';}for(int i = 0; i < n; i++)cout<<g[i]<<endl;}return 0; }總結
以上是生活随笔為你收集整理的codeforces 706 div2题解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: web api 数独 求解代码 使用穷举
- 下一篇: 计算机科学与遥感信息技术学院,2021年