C - Dean and Schedule --贪心

好好的一道题。。被我错成这样。。唉。。。思路一开始就少注意到一个很重要的情况,给奇数偶数的问号插入字母时,需要先找到未出现过的、最优的字母

在需要填字母时

如a b c d ....w x y z

   1 0 1 0      0 1 1 1

未用过的字母中

显然b比w更靠近边界,所以 优先选b 填在偶数位!  但是很重要的是,如果这时偶数位已经填满了! 就得填奇数位的!就是漏了这一点,又WA多次。。。

唉,分类还是总少考虑了情况

题目连接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=61977


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std; 

char tm[100000+5];
int mark[28];
int que[100000+5];
int vis[100000+5];

int main()

{
	
	int odd=0;
	int even=0;
	int i,k;
	scanf("%s",tm+1);
	scanf("%d",&k);
	int len=strlen(1+tm);
	int question=0;
	int ok=0;
	
	for (i=1;i<=len;i++)
	{
		if (tm[i]=='?')
		{
			question++;
			que[++ok]=i;
			if (i%2==1)  odd++;
			else
				even++;
		}
		else
		{
			mark[tm[i]-'a'+1]=1;
		}
	}
	int j;
	int kind=0;
	for (i=1;i<=26;i++)
	{
		if (mark[i]) 
			kind++;
	}
	
	if (kind>=k)
	{
		if (question==0)
		{
			printf("%s\n",tm+1);
			return 0;
		}
		else
		{
			
			for (i=1;i<=ok;i++)
			{
				if (que[i]%2==1&&vis[que[i]]==0)
				{
					tm[que[i]]='z';
					vis[que[i]]=1;
				}
				if (que[i]%2==0&&vis[que[i]]==0)
				{
					tm[que[i]]='a';
					vis[que[i]]=1;
				}
			}
			printf("%s\n",tm+1);
			return 0;
		}
	}
	else
		if (kind<k)
		{
			
			int need=k-kind;
			
			if (need>odd+even)
			{
				printf("-1\n");
				return 0;
			}
			// then need<= odd+even=question


			while(need--)
			{
				int j1,j2;
				for (j1=26;j1>=1;j1--)
				{
					if (mark[j1]==0) break;
				}
				for (j2=1;j2<=26;j2++)
				{
					if (mark[j2]==0) break;
				}
				int o_e;
				if ((26-j1)<j2-1)	o_e=0;  //odd离两端较近,选之
				else
					o_e=1;

				if (o_e==0&&odd||!even)   
				{
					for (i=1;i<=ok&&odd;i++)
					{
						if (que[i]%2==1&&vis[que[i]]==0)
						{
							
							
							tm[que[i]]=j1-1+'a';
							vis[que[i]]=1;
							o_e=1;
							odd--;
							mark[j1]=1;
							
							break;
						} 
					}
				}
				else		//去掉一个偶数min
				{
					for (i=1;i<=ok&&even;i++)
					{
						if (que[i]%2==0&&vis[que[i]]==0)
						{
							
							tm[que[i]]=j2-1+'a';
							vis[que[i]]=1;
							mark[j2]=1;
							o_e=0;
							even--;
							//	change++;
							break;
						} 
					}
					
					
				} 
			}
			if (odd)
			{
				for (i=1;i<=ok;i++)
				{
					if (que[i]%2==1&&vis[que[i]]==0)
					{
						tm[que[i]]='z';
						vis[que[i]]=1;  
						odd--;
						if (odd==0) break;
					} 
					
				}
				
			}
			if (even)
			{
				for (i=1;i<=ok;i++)
				{
					if (que[i]%2==0&&vis[que[i]]==0)
					{
						tm[que[i]]='a';
						vis[que[i]]=1;
						even--;
						if (even==0) break;
					} 
				} 
			}
			printf("%s\n",tm+1);
			return 0;
		}
		
		
		
		
		
		
		
		
		return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值