UVA1623 神龙喝水 Enter The Dragon 题解

思路:

如果遇到一个暴雨天,即a[i]!=0的日子

就找在这个日子之前,且在上一次a[i]之后的日子里的晴天.

我直接用了map来存一个x号池塘的上一次出现的位置. m[x]

即只需找从[m[x],i]中的晴天(由贪心,应该尽量靠前,才能保证有尽量多的雨天能分配到晴天的日子让龙来吸水)

这题修改了许多次

第一次想用vector来存晴天的日子,然后从vector中找大于m[x]的第一个日子,结果TLE

​​​​​​​​​​​​​​		for(int i=1;i<=day;i++)
		{
			int x;
			scanf("%d",&x);
			d[i]=x;
			if(x==0)
			{
				w.push_back(i);
			}
			else
			{
				if(w.size()==0)
				{
					ok=0;
				}
				else
				{
					auto k=w.begin();
					
					for(;k!=w.end();k++)
					{
						if(*k>=m[x])
						{
							break;
						}
					}
					if(k==w.end())
					{
						ok=0;
					}
					else 
					{
						num[*k]=x;
						w.erase(k);
					}
				}
				m[x]=i;
			}
			
		}

第二次采用二分在vector中找,结果还是TLE.

		for(int i=1;i<=day;i++)
		{
			int x;
			scanf("%d",&x);
			d[i]=x;
			if(x==0)
			{
				w.push_back(i);
			}
			else
			{
				if(w.size()==0)
				{
					ok=0;
				}
				else
				{
					auto k=w.begin();
					int l=0,r=w.size()-1;
					while(l<r)
					{
						int mid=(l+r)/2;
						//printf("%d vs %d\n",w[mid],m[x]);
						if(w[mid]>=m[x]) r=mid;
						else l=mid+1;
					}
					k+=l;
//					for(;k!=w.end();k++)
//					{
//						if(*k>=m[x])
//						{
//							break;
//						}
//					}
					if(k>=w.end()||w[l]<=m[x])
					{
						ok=0;
					}
					else 
					{
						num[*k]=x;
					//	printf("第%d\n",*k);
						w.erase(k);
					}
				}
				m[x]=i;
			}
			
		}

最后采用了set来存储才AC

s.lower_bound(x) 表示集合s中不小于x的最小的数

AC代码献上

#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<string.h>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;
const int N=1e6+10;
int d[N]={0};
int num[N]={0};
		
int main()
{
	//freopen("uva1623.txt","r",stdin);
	//freopen("uva1623-out.txt","w",stdout);
	int T;
	scanf("%d",&T);
	while(T--)
	{
		memset(d,0,sizeof d);
		memset(num,0,sizeof num);
		int num_lake=0,day=0;
		scanf("%d%d",&num_lake,&day);
		//const int N=1e6+10;
		set<int> w;
		map<int,int>m;
		int ok=1;
		
		
		for(int i=1;i<=day;i++)
		{
			int x;
			scanf("%d",&x);
			d[i]=x;
			if(x==0)
			{
				w.insert(i);
			}
			else
			{
				if(w.size()==0)
				{
					ok=0;
				}
				else
				{
					auto k=w.lower_bound(m[x]);
					if(k!=w.end())
					{
						num[*k]=d[i];
						w.erase(k);
						
					}else ok=0;
				}
				m[x]=i;
			}
			
		}
		if(ok)
		{
			printf("YES\n");
			
			int haveprint=0;
			for(int i=1;i<=day;i++)
			{
				if(d[i]==0)
				{
					if(haveprint)
					{
						printf(" ");
					}
					printf("%d",num[i]);
					haveprint=1;
				}
			}
			printf("\n");
		}
		else printf("NO\n");
	}
	return 0;
}

posted @ 2022-09-17 19:35  LZH_03  阅读(20)  评论(0编辑  收藏  举报