zoukankan      html  css  js  c++  java
  • CF118C Fancy Number(模拟)

    细节还是挺多的

    首先找一个使得价值最小的数,注意这个数可能有很多,我们都要把它们存下来,然后尝试更改,注意字典序问题,从后到前还是从前到后更改。

    其中有贪心思想:设最后更改为x,则按照x+1,x-1,x+2,x-2...顺序更改。

    注意char数组比较字典序不能直接用小于号来比较

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=500005;
    typedef long long ll;
    int p,n,k,maxn,pos[N];
    ll maxx=1e18;
    int read(){
    	int num=0,f=1;
    	char c=getchar();
    	while(c<'0'||c>'9'){
    		if(c=='-') f=-1;
    		c=getchar();
    	}
    	while(c>='0'&&c<='9'){
    		num=num*10+c-'0';
    		c=getchar();
    	}
    	return num*f;
    }
    char s[N],anss[N],ss[N]; 
    int xx;
    int b[N][10],cnt[10],tot[10];
    ll solve(int x,int rest){
    	int res=0;
    	int d=1;
    	while(rest){
    		if(x+d>9){
    			d=-d;
    			continue;
    		}
    		if(x+d<0){
    			d=-(d-1);
    			continue;
    		}
    		if(abs(d)>9) break;
    		if(rest<=cnt[x+d]){
    			tot[x+d]+=rest;
    			res+=abs(d)*rest;
    			rest=0;
    		}
    		if(rest>cnt[x+d]){
    			rest-=cnt[x+d];
    			tot[x+d]+=cnt[x+d];
    			res+=abs(d)*cnt[x+d];
    		}
    		if(d<0) d=-(d-1);
    		else d=-d;
    	}
    	return res;
    }
    bool cmp(char *a,char *b){
    	for(int i=0;i<n;i++){
    		if(a[i]==b[i]) continue;
    		else if(a[i]>b[i]) return 1;
    		else return 0;
    	}
    	return 1;
    }
    int main(){
    	n=read(); k=read();
    	anss[1]='-';
    	scanf("%s",s+1);
    	for(int i=1;i<=n;i++){
    		cnt[s[i]-'0']++;
    		maxn=max(maxn,cnt[s[i]-'0']);
    	}
    	if(maxn>=k){
    		printf("0
    ");
    		printf("%s",s+1);
    		return 0;
    	}
    	for(int i=0;i<=9;i++){
    		if(!cnt[i]) continue;
    		memset(tot,0,sizeof(tot));
    		ll tmp=solve(i,k-cnt[i]);
    		if(maxx>tmp){
    			maxx=tmp;
    			xx=1; 
    			pos[xx]=i;
    			for(int j=0;j<=9;j++) b[xx][j]=tot[j];
    		}
    		else if(maxx==tmp){
    			maxx=tmp;
    			pos[++xx]=i;
    			for(int j=0;j<=9;j++) b[xx][j]=tot[j];
    		}
    	}
    	for(int k=1;k<=xx;k++){
    		for(int i=1;i<=n;i++) ss[i]=s[i];
    		for(int i=0;i<=9;i++){
    			if(i<pos[k]){
    				if(b[k][i]){
    					for(int j=n;j>=1;j--){
    						if(s[j]-'0'==i){
    							ss[j]=(char)(pos[k]+'0');
    							b[k][i]--;
    						}
    						if(b[k][i]==0) break;
    					}
    				}
    			}
    			else{
    				if(b[k][i]){
    					for(int j=1;j<=n;j++){
    						if(s[j]-'0'==i){
    							ss[j]=(char)(pos[k]+'0');
    							b[k][i]--;
    						}
    						if(b[k][i]==0) break;
    					}
    				}
    			}
    		}
    		if(anss[1]=='-') for(int p=1;p<=n;p++) anss[p]=ss[p];
    		if(cmp(anss,ss)) for(int p=1;p<=n;p++) anss[p]=ss[p];
    	}
    	printf("%lld
    ",maxx);
    	cout<<anss+1;
    	return 0;
    }
    
  • 相关阅读:
    网页动画
    浮动
    定位
    盒子模型
    表单
    2017年07月05号课堂笔记
    2017年07月07号课堂笔记
    2017年07月03号课堂笔记
    2017年06月30号课堂笔记
    2017年06月28号课堂笔记
  • 原文地址:https://www.cnblogs.com/New-ljx/p/15367482.html
Copyright © 2011-2022 走看看