比赛链接:https://codeforces.com/contest/1750
题意:给定长度为N的序列,你可以执行以下操作任意次
1:选择三个下标 i,j,k(1
2:如果ai>ak,ai=ai+aj,否则swap(aj,ak)
问能否将序列换成不降序列
分析:其实看样例也能发现规律。那就是,序列的第一个元素为1,就能实现,否则就不能实现。
证明:我们发现,如果序列第一个元素为1,则一定是整个序列最小的数,所以就可以一直交换aj和ak,那么我们肯定是能够将序列转变为不降序列的。如果序列第一个元素不为1,则最小的元素一定在后面(除了第一个位置的任意位置),那么我们是不可能通过操作将1放在第一个位置上的,因此就不能实现不降序列。即证!
代码:
- #include
- #define int long long
- using namespace std;
- const int N=2e5+10;
- int a[N];
-
- inline void solve(){
- int n;cin>>n;
- for(int i=1;i<=n;i++) cin>>a[i];
- if(a[1]==1) cout<<"Yes\n";
- else cout<<"No\n";
- }
-
- signed main(){
- int t;cin>>t;
- while(t--) solve();
- }
题意:给定一个长度为n的01串,定义一个串的价值为:如果串中存在0和1,那么价值为0和1个数的乘积,否则是某一种数数量的平方。求原串的某一连续子串的最大价值。
分析:我们发现,最大值只有三种情况才能取得:
(我们定义一个串中0的个数为a,1的个数为b)
1:max=a*b
2:max=x*x (x为串中0连续的最大长度)
3:max=y*y(y为串中1连续的最大长度)
所以我们只需要枚举串中这三个值即可
代码:
- #include
- #define int long long
- using namespace std;
- const int N=2e5+10;
- string s;
-
- inline void solve(){
- int n;cin>>n>>s;
- int a=0,b=0;
- for(int i=0;i<=n-1;i++)
- if(s[i]=='0') a++;
- else b++;
- int maxx=a*b;
- a=0,b=0;int x,y;
- for(int i=0;i<=n-1;){
- while(s[i]=='0') a++,i++;
- x=a*a;a=0;
- while(s[i]=='1') b++,i++;
- y=b*b;b=0;
- maxx=max(maxx,max(x,y));
- }
- cout<
"\n"; - }
-
- signed main(){
- int t;cin>>t;
- while(t--) solve();
- }
题意:给定两个长度都为n的01串a和b。每次我们可以对串进行操作,每次操作选择一段区间[l, r],使得a串[l, r]范围内的01翻转,b串除了[l, r]范围内的01翻转,请问能否将ab串置0,并输出方案。
分析:这里引用splay的题解吧,讲的挺好的。
代码:
- #include
- #define int long long
- using namespace std;
- typedef pair<int,int> PII;
- const int N=2e5+10;
-
- inline void solve(){
- int n;cin>>n;
- string s1,s2;cin>>s1>>s2;
- s1="*"+s1;s2="*"+s2;
- int cnt=0,cnt1=0,cnt2=0;
- for(int i=1;i<=n;i++){
- if(s1[i]==s2[i]){//统计相同位置的字符情况
- if(s1[i]=='0') cnt1++;//为0的个数
- else cnt2++;//为1的个数
- }
- else cnt++;//统计相同位置不同字符的个数
- }
- if(cnt!=0&&cnt!=n){
- cout<<"NO\n";return;
- }
- if(cnt1==n){//全为0的情况
- cout<<"YES\n";
- cout<<"0\n";
- return;
- }
- if(cnt2==n){//全是1
- cout<<"YES\n";
- cout<<2<<"\n";
- cout<<1<<" "<<1<<"\n";
- cout<<2<<" "<
"\n"; - return;
- }
- vector
ans; - int cur=0;
- if(cnt) cur++;
- for(int i=1;i<=n;i++){
- if(s1[i]=='1'){
- ans.push_back({i,i});
- cur++;
- }
- }
- if(cur&1){
- ans.push_back({1,1});
- ans.push_back({2,n});
- ans.push_back({1,n});
- }
- cout<<"YES\n";
- cout<
size()<<"\n"; - for(auto i:ans) cout<
" "<"\n"; -
- }
-
- signed main(){
- int t;cin>>t;
- while(t--) solve();
- }