1. 程式人生 > >【牛客 - 301哈爾濱理工大學軟體與微電子學院第八屆程式設計競賽同步賽(高年級 )】小樂樂和25(模擬,技巧)

【牛客 - 301哈爾濱理工大學軟體與微電子學院第八屆程式設計競賽同步賽(高年級 )】小樂樂和25(模擬,技巧)

題幹:
 

小樂樂特別喜歡25這個數字,他想把所有的數字都變成25的倍數。
現在小樂樂得到一個數字,想問問你最少用幾次操作才可以把這個數字改造成25的倍數。
對於一次操作我們可以把相鄰的兩位做交換,比如123經過一次操作之後就可以變成213或者132。

 

輸入描述:

多組資料輸入

對於每組資料,只有一行輸入一個整數n(1 <= n <= 1000000000)。

輸出描述:

如果經過最少x次操作後,這個數就變成了25的倍數,那麼輸出x;

如果這個數無論怎麼變化都變不成25的倍數,輸出-1.

示例1

輸入

複製

2018

輸出

複製

-1

示例2

輸入

複製

2020

輸出

複製

1

說明

經過一次之後變成2200

 

解題報告:

   因為一共就四種情況,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);
	}
}