zoukankan      html  css  js  c++  java
  • 算法竞赛入门经典 笔记(1)

    P144 UVa12657 移动盒子 Boxes in a Line

    #include<cstdio>
    typedef long long LL;
    LL n,m;
    LL l[100010],r[100010],p;//双向链表
    LL case1;//记录这是第几种情况
    int main()
    {
    	LL t,ans,i,a,x,y,k;
    	while(scanf("%lld%lld",&n,&m)==2)
    	{
    		p=0;//记录现在顺序是正的还是反的
    		for(i=1;i<=n;i++)
    		{
    			l[i]=i-1;r[i]=i+1; 
    		}
    		for(i=1;i<=m;i++)
    		{
    			scanf("%lld",&a);
    			if(a==4)
    				p=!p;
    			else
    			{
    				if(a!=3&&p)	a=3-a;//忘了加导致错,因为如果p不为0表示顺序是颠倒的
    				//而我们只是记录了p,并没有实际颠倒过来,因此p不为0时操作左侧实际要右侧,操作右侧实际要操作左侧
    				scanf("%lld%lld",&x,&y);
    				if(a==1)
    				{
    					if(x==l[y])	continue;//忘了加,其实可以不加
    					r[l[x]]=r[x];
    					l[r[x]]=l[x];
    					r[l[y]]=x;
    					l[x]=l[y];
    					r[x]=y;
    					l[y]=x;
    				}
    				if(a==2)
    				{
    					if(x==r[y])	continue;//忘了加,其实可以不加
    					r[l[x]]=r[x];
    					l[r[x]]=l[x];
    					l[r[y]]=x;
    					r[x]=r[y];
    					l[x]=y;
    					r[y]=x;
    				}
    				if(a==3)
    				{
    					if(r[y]==x)
    					{
    						t=y;
    						y=x;
    						x=t;
    					}
    					if(r[x]==y)
    					{
    						r[l[x]]=y;
    						l[r[y]]=x;
    						l[y]=l[x];
    						r[x]=r[y];
    						l[x]=y;
    						r[y]=x;
    					}
    					//曾经忽略了x、y相邻时交换的特殊情况,就是上面的情况,导致错误
    					else
    					{
    						r[l[x]]=y;
    						r[l[y]]=x;
    						l[r[x]]=y;
    						l[r[y]]=x;
    						t=r[x];
    						r[x]=r[y];
    						r[y]=t;
    						t=l[x];
    						l[x]=l[y];
    						l[y]=t;
    					}
    				}
    			}
    		}
    		t=0;
    		ans=0;
    		if(p==0)
    		{
    			for(i=1;i<=n;i++)
    				if(l[i]==0)
    				{
    					k=i;
    					while(k!=n+1)
    					{
    						t=not t;
    						if(t)
    							ans+=k;
    						k=r[k];
    					} 
    					break;
    				}
    		}
    		else
    		{
    			for(i=1;i<=n;i++)
    				if(r[i]==n+1)
    				{
    					k=i;
    					while(k!=0)
    					{
    						t=not t;
    						if(t)
    							ans+=k;
    						k=l[k];
    					}
    				}
    		}
    		printf("Case %lld: %lld
    ",++case1,ans); 
    	}
    	return 0;
    }

    P138 UVa212 医院设备利用 Use of Hospital Facilities

    #include<iostream>
    #include<cstring>
    //出过错:病人要去的恢复室,是根据做完手术那一刻编号最小的空的恢复室决定的
    //而不是到之后编号最小的空的恢复室
    //出过错:那个the patient with the lower number指的是在门牌号小的手术室做手术的患者。那个number竟然指的门牌号!http://www.cnblogs.com/xienaoban/p/6798078.html
    #include<string>
    #include<queue>
    using namespace std;
    struct Patient
    {
    	string name;
    	int room,b1,e1,bed,b2,e2;//分别记录病人的手术室,手术开始时间,手术结束时间,恢复室,恢复开始时间,恢复结束时间
    	int t1,t2;//分别记录病人的手术和恢复时间
    }pt[110];
    int rm[11],bd[31];//记录room和bed的使用时间
    struct Query
    {
    	int room,end,ptn;
    	Query(){}
    	Query(int b,int c,int d)
    	{
    		room=b;end=c;ptn=d;
    	}
    	friend bool operator<(const Query&a,const Query& b)
    	{
    		return (a.end>b.end)||(a.end==b.end&&a.room>b.room)||(a.end==b.end&&a.room==b.room&&a.ptn>b.ptn);
    	}//这个排序对于病人做手术、从手术出来、恢复的排序都有效
    };
    int q_num=0;
    priority_queue<Query> q1;
    priority_queue<Query> q2;//记录病人从手术室出来的顺序(就是pop的顺序)、结束时间(end)、做手术的房间(room)
    bool boo[31];
    int n,m,T,t1,t2,t3,k,maxt;
    int main()
    {
    	int i;
    	while(scanf("%d%d%d%d%d%d%d",&n,&m,&T,&t1,&t2,&t3,&k)==7)//出过错:当成单组数据了
    	{
    		memset(boo,0,sizeof(boo));
    		memset(rm,0,sizeof(rm));
    		memset(bd,0,sizeof(bd));
    		maxt=-1;
    		T=60*T;
    		for(i=1;i<=k;i++)
    		{
    			cin>>pt[i].name;
    			scanf("%d%d",&pt[i].t1,&pt[i].t2);
    		}
    		Query qt,qt2;
    		for(i=1;i<=min(n,k);i++)
    		{
    			q1.push(Query(i,pt[i].t1+T,i));
    			pt[i].b1=T;
    			pt[i].room=i;
    		}
    		for(i=min(n,k)+1;i<=k;i++)
    		{
    			qt=q1.top();
    			q1.pop();
    			rm[qt.room]+=pt[qt.ptn].t1;
    			pt[qt.ptn].e1=qt.end;
    			q1.push(Query(qt.room,qt.end+t2+pt[i].t1,i));
    			pt[i].b1=qt.end+t2;
    			pt[i].room=qt.room;
    			q2.push(Query(qt.room,qt.end,qt.ptn));
    		}
    		while(!q1.empty())
    		{
    			qt=q1.top();
    			q1.pop();
    			rm[qt.room]+=pt[qt.ptn].t1;
    			pt[qt.ptn].e1=qt.end;
    			q2.push(Query(qt.room,qt.end,qt.ptn));
    		}
    	//	while(!q2.empty())
    	//	{
    	//		qt=q2.top();
    	//		q2.pop();
    	//		printf("%d %d %d
    ",qt.end,qt.ptn,pt[qt.ptn].t2+qt.end);
    	//	}
    	//	for(i=1;i<=n;i++)
    	//		printf("%d %d
    ",i,rm[i]);
    	//	for(i=1;i<=k;i++)
    	//		printf("%d %d %d
    ",pt[i].room,pt[i].b1,pt[i].e1);
    		while(!q2.empty())
    		{
    			qt=q2.top();
    			q2.pop();
    			while(!q1.empty())
    			{
    				qt2=q1.top();
    				if(qt2.end+t3<=qt.end)//出过错:没加等号
    				{
    					q1.pop();
    					pt[qt2.ptn].e2=qt2.end;
    					boo[qt2.room]=false;
    					bd[qt2.room]+=pt[qt2.ptn].t2;
    					maxt=max(maxt,qt2.end);
    				}
    				else
    					break;
    			}
    			for(i=1;i<=m;i++)
    				if(boo[i]==false)
    				{
    					boo[i]=true;
    					q1.push(Query(i,qt.end+pt[qt.ptn].t2+t1,qt.ptn));
    					pt[qt.ptn].b2=qt.end+t1;
    					pt[qt.ptn].bed=i;
    					break;
    				}
    		}
    		while(!q1.empty())
    		{
    			qt2=q1.top();
    			q1.pop();
    			maxt=max(maxt,qt2.end);
    			bd[qt2.room]+=pt[qt2.ptn].t2;
    			pt[qt2.ptn].e2=qt2.end;
    		}
    		printf(" Patient          Operating Room          Recovery Room
    ");  
    	    printf(" #  Name     Room#  Begin   End      Bed#  Begin    End
    ");  
    	    printf(" ------------------------------------------------------
    ");
    		for(i=1;i<=k;i++)
    			printf("%2d  %-10s%2d   %2d:%02d   %2d:%02d     %2d   %2d:%02d   %2d:%02d
    ",i,pt[i].name.c_str(),pt[i].room,pt[i].b1/60,pt[i].b1%60,pt[i].e1/60,pt[i].e1%60,pt[i].bed,pt[i].b2/60,pt[i].b2%60,pt[i].e2/60,pt[i].e2%60);
    		printf("
    Facility Utilization
    Type  # Minutes  % Used
    ");
    		printf("-------------------------
    ");
    		maxt-=T;
    		for(i=1;i<=n;i++)
    			printf("Room %2d    %4d   %5.2f
    ",i,rm[i],(double)rm[i]*100/maxt);
    		for(i=1;i<=m;i++)
    			printf("Bed  %2d    %4d   %5.2f
    ",i,bd[i],(double)bd[i]*100/maxt);
    		printf("
    ");//注意:不要少空行
    	}
    	return 0;
    }

    P148 UVa 679 小球下落 Dropping Balls

    点击打开链接


    记在滚某个球时,滚到节点i的次数为a[i]

    显然,如果a[i]为奇数,那么a[i*2]为(a[i]+1)/2,a[i*2+1]为(a[i]-1)/2(如果直接整除的话也可以表示为a[i]/2)

    (原因是a[i]为奇数,那么前面a[i]-1次必定是左右各走(a[i]-1)/2次,这一次必定是向左走)

    如果a[i]为偶数,那么a[i*2]=a[i*2+1]=a[i]/2

    而且如果a[i]为奇数,那么下一步会往a[i*2]走

    如果a[i]为偶数,那么下一步会往a[i*2+1]走

    显然a[1]就是题目中的I,那么现在可以求出叶子节点了

    这再次说明了写程序不如多想想

    P154

    对比:

    #include<cstdio>
    int b[100000001];
    int *a;
    int main()
    {
    	int i;
    	a=(int*)&b;
    	*a=29;
    	for(int i=1;i<=100000000;i++)
    		*(a+i)=(*(a+i-1)+*(a+i-2))*2%10000000;
    	printf("%d",*(a+10000000));
    }
    #include<cstdio>
    int b[100000001];
    int *a;
    int main()
    {
    	int i;
    	a=(int*)&b;
    	*a=29;
    	for(i=1;i<=100000000;i++)
    		b[i]=(b[i-1]+b[i-2])*2%10000000;
    	printf("%d",b[10000000]);
    }
    内存池

    P160 UVa 297 四分树 Quadtrees

    输出测试数据(?):

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    int a[33][33];
    void print(int l1,int l2,int w)
    {
    	bool b1=false,b2=false;
    	int i,j;
    	if(w==1)
    	{
    		if(a[l1][l2]==0)
    			printf("e");
    		else
    			printf("f");
    		return;
    	}
    	for(i=0;i<w;i++)
    		for(j=0;j<w;j++)
    		{
    			if(a[l1+i][l2+j]==0)
    				b1=true;
    			if(a[l1+i][l2+j]==1)
    				b2=true;
    			if(b1&&b2)
    				goto haha;
    		}
    	haha:
    	if(b1&&(!b2))
    		printf("e");
    	else if((!b1)&&b2)
    		printf("f");
    	else
    	{
    		printf("p");
    		print(l1+w/2,l2,w/2);
    		print(l1,l2,w/2);
    		print(l1,l2+w/2,w/2);
    		print(l1+w/2,l2+w/2,w/2);
    	}
    }
    int main()
    {
    	int i,j;
    	srand(time(0));
    	printf("1
    ");
    	memset(a,0,sizeof(a));
    	for(i=1;i<=32;i++)
    		for(j=1;j<=32;j++)
    			a[i][j]=rand()%2;
    	print(1,1,32);
    	printf("
    ");
    	for(i=1;i<=32;i++)
    		for(j=1;j<=32;j++)
    			a[i][j]=rand()%2;
    	print(1,1,32);
    }
    程序:

    #include<cstdio>
    #include<cstring>
    int ans;//答案
    int buf[35][35];//记录draw出来的正方形
    char s[2000];//曾经未注意,开太小了,实际上最大远远大于32*32,因为一个2*2的格子,最多占5个字符而不是4个,更多的类似 
    int p,n;//当前字符序号
    //把s绘制到以(r,c)为左上角,边长为w的buf中
    void draw(const char* s,int r,int c,int w)
    {
    	char ch=s[p++];
    	int i,j; 
    	if(ch=='p')
    	{
    		draw(s,r+w/2,c,w/2);
    		draw(s,r,c,w/2);
    		draw(s,r,c+w/2,w/2);
    		draw(s,r+w/2,c+w/2,w/2);
    		//举例:最开始0-31,0-31
    		/*分开:
    		1:16-31,0-15
    		2:0-15,0-15
    		3:0-15,16-31
    		4:16-31,16-31
    		*/
    	}
    	else if(ch=='f')
    		for(i=0;i<w;i++)
    			for(j=0;j<w;j++)
    				if(buf[r+i][c+j]==0)
    				{
    					ans++;
    					buf[r+i][c+j]=1;
    				}
    }
    int main()
    {
    	int i;
    	scanf("%d",&n);
    	for(i=1;i<=n;i++)
    	{
    		ans=0;
    		//memset(s,0,sizeof(s));
    		memset(buf,0,sizeof(buf)); 
    		scanf("%s",s);
    		p=0;
    		draw(s,0,0,32);
    		scanf("%s",s);
    		p=0;
    		draw(s,0,0,32);
    		printf("There are %d black pixels.
    ",ans);
    	}
    	return 0;
    }


  • 相关阅读:
    【hdu 2569】ACM程序设计期末考试081230
    【信息安全111班暑期学习工作任务】
    【hdu 1698 Just a Hook(被搞死)】
    Win8下安装 .net framework 3.5.1 无需连网安装方法,证实有效
    【UVA 488 Triangle Wave】
    【As Easy As A+B 专题训练排序】
    【hdu 1787 GCD Again (数论、欧拉函数)】
    【hdu 2602 Bone Collector(动态规划、01背包)】
    【poj 1953 World Cup Noise】
    【poj 2478 Farey Sequence (欧拉函数、数论)】
  • 原文地址:https://www.cnblogs.com/hehe54321/p/8470439.html
Copyright © 2011-2022 走看看