codeforces 330A 330B 329A 分别是7月20DIV2的前三题

  题目地址:A. Cakeminator  B. Road Construction  C. Purification

    都是思维题目,自己思想很不着调啊,还得多多练习。


A. Cakeminator

/*
     题目想复杂了,每一行或一列有东西就可以吃,at least one cake 可自己却看成了至少两个(num>1改成num>=1)........,悲剧了,然后就纠结先行还是先列,
	       于是s1,s2再判断哪个更大。 

*/
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<iomanip>
using namespace std;

int rr[12];
int cc[12];
//int map1[12][12];
int main()
{
   int r,c,i,j;
   char a;
   while(cin>>r>>c)
   {
	   memset(rr,0,sizeof(rr));
	   memset(cc,0,sizeof(cc));
	   //memset(map1,0,sizeof(map1));
       for(i=0;i<r;i++)
		   for(j=0;j<c;j++)
		   {
                 cin>>a;
				 if(a=='S')
				 {
				     rr[i]=1;
					 cc[j]=1;
					 //map1[i][j]=1;
				 }
		   }

	   int flag=0;
	   int s1=0,s2=0;
       for(i=0;i<r;i++)
		   if(!rr[i])
		   {
		       s1+=c;
			   //for(j=0;j<c;j++)
				   //map1[i][j]=2;
			   flag++;
		   }
	   for(i=0;i<c;i++)
		   if(!cc[i])
		   {
			  //int num=0;
		      //for(j=0;j<r;j++)
				  //if(map1[j][i]==0)
					  //num++;
			  //if(num>=1)
				  //s1+=num;
			   s1+=r-flag;
		   }
       
        /*memset(map1,0,sizeof(map1));
		for(i=0;i<c;i++)
		   if(!cc[i])
		   {
		       s2+=r;
			   for(j=0;j<r;j++)
				   map1[j][i]=2;
		   }

	   for(i=0;i<r;i++)
		   if(!rr[i])
		   {
			  int num=0;
		      for(j=0;j<c;j++)
				  if(map1[i][j]==0)
					  num++;
			  if(num>=1)
				  s2+=num;
		   }

	   if(s1>s2)*/
		   cout<<s1<<endl;
	     //else
		//	 cout<<s2<<endl;
	   
   }
   return 0;
}

 B. Road Construction

/*
     it is possible to go from each city to any other city by traversing at most two roads
	 神啊,题目说的原来是5-1-2-3这样的路是不可行的,那么所有的点必须连在一个点上,on my god!!!!
	 我居然还手写了并查集判断他们是否联通。。。。
*/

#include<iostream>
using namespace std;
int visi[1002];
int main()
{
	int n,m,i;
	int a,b;
	while(cin>>n>>m)
	{
	    for(i=1;i<=m;i++)
		{
		    cin>>a>>b;
			visi[a]=1;
			visi[b]=1;
		}
		int t=0;
		for(t=1;t<=n;t++)
			if(!visi[t])
				break;
		cout<<n-1<<endl;
		for(i=1;i<=n;i++)
			if(i!=t)
				cout<<t<<" "<<i<<endl;
	}
    return 0;
}

C. Purification

/*
     定式思维不能突破啊!!!
	 每一行或每一列如果都有一个点,随便输出行的一个点,则整张图就全部访问了。
	   自己却用了tt数组num数组来保存每个点可以消去的数目。
	   但是那样做却不是最简单的手法,而且会有漏洞,没有整体的思想。。。。。
*/

#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<iomanip>
using namespace std;

int map1[102][102];   //保存妖怪
//int num[10002],t;       //保存每个点可以消灭妖怪的数目
//int tt[10002][2];    //保存点
//int visi[102][102];     //还有一个条件,是后来看第一个测试数据时发现的
//int visitt[10002];      //点有没有被访问
int dianr[102];     //行数有点
int dianc[102];     //列数有点
int n;
int res[1002][2];   //保留最后的结果

/*void cal()
{
	int k,i;
    for(k=1;k<=t;k++)
	{
		for(i=1;i<=n;i++)
		  num[k]+=map1[tt[k][0]][i];
		for(i=1;i<=n;i++)
		  num[k]+=map1[i][tt[k][1]];
	}
}

int judge()
{
    int i,j;
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			if(!visi[i][j])
				return 0;
	return 1;
}*/

int main()
{
   int i,j,k,step;
   char a;
   while(cin>>n)
   {
	   memset(map1,0,sizeof(map1));
	   //memset(num,0,sizeof(num));
	   //memset(visi,0,sizeof(visi));
       memset(dianr,0,sizeof(dianr));    //行数有点则为1
	   memset(dianc,0,sizeof(dianc));    //列数有点则为1
	   //memset(visitt,0,sizeof(visitt));
       for(i=1;i<=n;i++)
         for(j=1;j<=n;j++)
		 {
		      cin>>a;
			  if(a=='E')
				 map1[i][j]=1;    //主要是统计每一个点处可以消灭妖怪的数量num
			    else 
				{
					//map1[i][j]=1;     //把点也加进去
					//tt[++t][0]=i;     //点的保存 0存储行 1存储列
					//tt[t][1]=j;
					dianr[i]=1;       
					dianc[j]=1;       
					//这两个主要是判断为-1的情况。行与列都为0则输出-1.
				}
		 }
	   
	   int t1=0,t2=0;
       for(i=1;i<=n;i++)
		   t1+=dianr[i],t2+=dianc[i];
	   if(t1==n)
	   {
		   for(i=1;i<=n;i++)
			   for(j=1;j<=n;j++)
				   if(!map1[i][j])
				   {
				       cout<<i<<" "<<j<<endl;
					   break;
				   }
	   }
		  else if(t2==n)
		  {
			  for(i=1;i<=n;i++)
			   for(j=1;j<=n;j++)
				   if(!map1[j][i])
				   {
				       cout<<j<<" "<<i<<endl;
					   break;
				   }
		  }
			 else
			 {
				 cout<<"-1"<<endl;
			 }
   }

   return 0;
}


你可能感兴趣的:(思维,codeforces)