【牛客 - 301哈尔滨理工大学软件与微电子学院第八届程序设计竞赛同步赛(高年级 )】小乐乐和25(模拟,技巧)

版权声明:欢迎学习我的博客,希望ACM的发展越来越好~ https://blog.csdn.net/qq_41289920/article/details/84801405

题干:
 

小乐乐特别喜欢25这个数字,他想把所有的数字都变成25的倍数。
现在小乐乐得到一个数字,想问问你最少用几次操作才可以把这个数字改造成25的倍数。
对于一次操作我们可以把相邻的两位做交换,比如123经过一次操作之后就可以变成213或者132。

输入描述:

多组数据输入

对于每组数据,只有一行输入一个整数n(1 <= n <= 1000000000)。

输出描述:

如果经过最少x次操作后,这个数就变成了25的倍数,那么输出x;

如果这个数无论怎么变化都变不成25的倍数,输出-1.

示例1

输入

复制

2018

输出

复制

-1

示例2

输入

复制

2020

输出

复制

1

说明

经过一次之后变成2200
扫描二维码关注公众号,回复: 4389503 查看本文章

解题报告:

   因为一共就四种情况,00,25,50,75,,,然后字符串从后往前找第一个出现的位置(或者用get函数了直接就从前往后找就行了。)维护答案就行了、注意一下前后位置,,因为如果前后位置是颠倒的话,,那就需要再多一次操作来正过来了,,因为我交换过来的时候肯定把我需要的这个另一个数字交换到后面去了。。所以需要再多一次操作。

AC代码:(其实这样直接判断的话就不需要用get函数了,,直接读入字符串然后带着字符做就行了。)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
const int INF = 0x3f3f3f3f;
int a[MAX],z[5];
int get(ll x) {
	int p = 0;
	while(x) {
		a[++p] = x%10;
		x/=10;
	}
	return p;
}
int main()
{
	ll n;
	while(~scanf("%lld",&n)) {
		int len = get(n);
		//for(int i = 1; i<=len; i++) printf("%d",a[i]);
		int ans = INF;
		int z0,z2,z5,z7,zero=0;
		//00
		for(int i = 1; i<=len; i++) {
			if(a[i] == 0) z[++zero] = i;
			if(zero==2) break;
		}
		if(zero==2) {
			ans = min(ans,(z[1]-1)+(z[2] - 2));
		}
		//25
		z2=-1,z5=-1;
		for(int i = 1; i<=len; i++) {
			if(a[i] == 2&&z2==-1) z2=i;
			if(a[i] == 5&&z5==-1) z5=i;
		}
		if(z2!=-1&&z5!=-1) {
			ans = min(ans,z2-2+z5-1+(z2<z5));
		}
		//50
		z0=z5=-1;
		for(int i = 1; i<=len; i++) {
			if(a[i] == 0&&z0==-1) z0=i;
			if(a[i] == 5&&z5==-1) z5=i;
		}
		if(z0!=-1&&z5!=-1) {
			ans = min(ans,z0-1+z5-2+(z5<z0));
		}		
		
		//75
		z7=-1,z5=-1;
		for(int i = 1; i<=len; i++) {
			if(a[i] == 7&&z7==-1) z7=i;
			if(a[i] == 5&&z5==-1) z5=i;
		}
		if(z7!=-1&&z5!=-1) {
			ans = min(ans,z7-2+z5-1+(z7<z5));
		}		
		if(ans == INF) puts("-1");
		else printf("%d\n",ans);
	}
	return 0 ;
 }

AC代码2:(直接n^2暴力就好了)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
const int INF = 0x3f3f3f3f;
int q[MAX];
int so(int i,int j) {
	return (i-2) + (j-1) + (i<j) ;
//	if(i>j)
//		return i+j-3;
//	return i+j-2;
}
int main() {
	int n;
	while(~scanf("%d",&n)) {
		if(n%25==0) {
			printf("0\n");
			continue;
		}
		int k=n,v=0,ans=INF;
		while(k) {
			q[++v]=k%10;
			k/=10;
		}
		for(int i=1; i<=v; i++)
			for(int j=i+1; j<=v; j++) {
				if((q[i]*10+q[j])%25==0) ans=min(ans,so(i,j));
				if((q[i]+q[j]*10)%25==0) ans=min(ans,so(j,i));
			}
		if(ans!=INF)
			printf("%d\n",ans);
		else
			printf("%d\n",-1);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_41289920/article/details/84801405