To_Heart—题解——令人窒息的操作

描述

题目描述

果果想出两个令⼈窒息的操作,给你⼀个字符串 以及两个整数 和 。其中字符串 的⻓度为偶数, 且仅由数字0到9组成。

你可以在s上按任意顺序多次执⾏下⾯两个操作之⼀:

操作1:将a加到s中所有下标为奇数的元素上(下标从0开始)。数字⼀旦超过9就会变成0, 如此循环往复。例如,s=“3456"且a=5,则执⾏此操作后s变成"3951”。

操作2将s向右轮转b位。例如,s=“3456"且b=1,则执⾏此操作后s变成"6345” 。

请你帮果果求出在s上执⾏上述操作任意次后可以得到的字典序最⼩的字符串。

所谓字典序,⽐如两个字符串abcdef,bcd从第⼀个字符开始⽐较,第⼀个字符不相等a<b所以第⼀ 个字典序较⼩。若第⼀个相等,继续⽐较后续字符⽐如hi,history若其中⼀个没有后续的字符了,则 较短的串字典序较⼩。

输入格式

输出的第⼀⾏包括⼀个字符串s。 第⼆⾏包括两个正整数a,b。

输出格式

输出只有⼀⾏,表示你的答案。

样例

样例输入 1

5525

9 2

样例输出 1

2050

样例解释 1

初始:5525

操作2:2555

操作1:2454

操作1:2353

操作2:5323

操作1:5222

操作1:5121

操作2:2151

操作1:2050

题解

首先,对于操作1,因为我们要保证字典序最小,所以尽量把能改变的所有数中最靠前的数改变为零,设最靠前的数为n,我们依次枚举n,(n+a)%10,…,(n+9*a)%10,然后在里面找到最小的即可,再通过其改变来将所有的可以改变的数都改变。

然后,针对操作2,我们把它所有的移动情况全部枚举出来
批注 2020-11-01 170851.png
根据裴蜀定理的推论(如上),可以确定移动过后的情况数最多有n-1种,再加上原来的数列,共有n种情况,开一个二维数组来存储所有情况,代码如下:

while(t!=0){
    
    
		++tot;  //tot为所有情况总数
		for(int i=0;i<n;i++){
    
    
			a[tot][i]=a[1][(i+t)%n];
		}
		t+=m;
		t%=n;
	}

但是,如果移动的次数为2的倍数,则原来的偶数位就永远是偶数位,永远无法进行操作1,所以进行分类讨论;
代码如下:

#include<bits/stdc++.h>
using namespace std;

int a[1005][1005];
bool f[1005];

int main(){
    
    
	char s[1005];
	cin>>s;
	int n=strlen(s);
	int m,x;
	scanf("%d%d",&x,&m);
	for(int i=0;i<n;i++){
    
    
		a[1][i]=s[i]-'0';
	}
	m%=n;
	if(m==0){
    
    
		int sum=a[1][1];
		int id=0;
		int now=sum;
		for(int i=1;i<=9;i++){
    
    
			int nownow=sum+x*i;
			if(nownow%10<now){
    
    
				now=nownow%10;
				id=i;
			}
		}
		for(int i=0;i<n;i++){
    
    
			if(i%2==1){
    
    
				printf("%d",(a[1][i]+x*id)%10);
			}
			else
				printf("%d",a[1][i]);
		}
		return 0;
	}
	int t=m;
	int tot=1;
	while(t!=0){
    
    
		++tot;
		for(int i=0;i<n;i++){
    
    
			a[tot][i]=a[1][(i+t)%n];
		}
		t+=m;
		t%=n;
	}
	if(m%2==0){
    
    
		for(int i=1;i<=tot;i++){
    
    
			int sum=a[i][1];
			int id=0;
			int now=sum;
			for(int j=0;j<=9;j++){
    
    
				int nownow=sum+x*j;
				if(nownow%10<now){
    
    
					now=nownow%10;
					id=j;
				}
			}
			for(int j=0;j<n;j++){
    
    
				if(j%2==1){
    
    
					a[i][j]=(a[i][j]+x*id)%10;
				}
			}
		}
		int nowmin=1;
		for(int j=0;j<n;j++){
    
    
			for(int i=1;i<=tot;i++){
    
    
				if(f[i])
					continue;
				if(a[i][j]>a[nowmin][j]){
    
    
					f[i]=1;
				}
				if(a[i][j]<a[nowmin][j]){
    
    
					f[nowmin]=1;
					nowmin=i;
				}
			}
		}
		for(int i=0;i<n;i++){
    
    
			printf("%d",a[nowmin][i]);
		}
		return 0;
	}
	for(int i=1;i<=tot;i++){
    
    
		int now_x=a[i][1];
		int id_x=0;
		int now_y=a[i][0];
		int id_y=0;
		for(int j=0;j<=9;j++){
    
    
			int nownow=a[i][1]+x*j;
			if(nownow%10<now_x){
    
    
				now_x=nownow%10;
				id_x=j;
			}
			nownow=a[i][0]+x*j;
			if(nownow%10<now_y){
    
    
				now_y=nownow%10;
				id_y=j;
			}
		}
		for(int j=0;j<n;j++){
    
    
			if(j%2==1){
    
    
				a[i][j]=(a[i][j]+x*id_x)%10;
			}
			else{
    
    
				a[i][j]=(a[i][j]+x*id_y)%10;
			}
		}
	}
	int nowmin=1;
	for(int j=0;j<n;j++){
    
    
		for(int i=1;i<=tot;i++){
    
    
			if(f[i])
				continue;
			if(a[i][j]>a[nowmin][j]){
    
    
				f[i]=1;
			}
			if(a[i][j]<a[nowmin][j]){
    
    
				f[nowmin]=1;
				nowmin=i;
			}
		}
	}
	for(int i=0;i<n;i++){
    
    
		printf("%d",a[nowmin][i]);
	}
	return 0;	
}
/*
43987654
7 3
*/

猜你喜欢

转载自blog.csdn.net/xf2056188203/article/details/109430597
今日推荐