程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> CF-192-diy-2

CF-192-diy-2

編輯:C++入門知識

題目意思:

給一個r*c的矩陣方格,有些位置有S,如果某一行和一列都不含標記為S的方格,則可以把該行所有方格都收掉,問最多能收多少個方格,方格可以收多次,多次收的方格計數一次。

解題思路:

暴力

代碼:


[cpp]
<SPAN style="FONT-SIZE: 18px">#include<iostream> 
#include<cmath>  
#include<cstdio>  
#include<cstdlib>  
#include<string>  
#include<cstring>  
#include<algorithm>  
#include<vector>  
#include<map>  
#include<set>  
#include<stack>  
#include<list>  
#include<queue>  
#define eps 1e-6  
#define INF 0x1f1f1f1f  
#define PI acos(-1.0)  
#define ll __int64  
#define lson l,m,(rt<<1)  
#define rson m+1,r,(rt<<1)|1  
using namespace std; 
 
/*
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
*/ 
 
char save[15][15]; 
bool flag[15][15]; 
struct Point 

   int x,y; 
}pp[120]; 
 
int main() 

   int r,c; 
 
   while(scanf("%d%d",&r,&c)!=EOF) 
   { 
      int cnt=0; 
      memset(flag,false,sizeof(flag)); 
      for(int i=1;i<=r;i++) 
      { 
         scanf("%s",save[i]+1); 
         for(int j=1;j<=c;j++) 
         { 
            if(save[i][j]=='S') 
            { 
               pp[++cnt].x=i; 
               pp[cnt].y=j; 
            } 
         } 
      } 
      for(int i=1;i<=r;i++) //掃描每一行  
      { 
         bool ff=true; 
         for(int j=1;j<=c;j++) //如果都沒有S,則標記這一行  
            if(save[i][j]=='S') 
            { 
               ff=false; 
               break; 
            } 
         if(ff) 
            memset(flag[i],true,sizeof(flag[i]));//表示能收  
      } 
      for(int i=1;i<=c;i++) //掃描每一列  
      { 
         bool ff=true; 
         for(int j=1;j<=r;j++) 
            if(save[j][i]=='S') 
            { 
               ff=false; 
               break; 
            } 
         if(ff) 
            for(int j=1;j<=r;j++) //標記這一列  
               flag[j][i]=true; 
      } 
 
      int ans=0; 
      for(int i=1;i<=r;i++) 
         for(int j=1;j<=c;j++) 
            if(flag[i][j]) //統計計數  
               ans++; 
      printf("%d\n",ans); 
   } 
   return 0; 

 
</SPAN> 

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#define eps 1e-6
#define INF 0x1f1f1f1f
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
using namespace std;

/*
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
*/

char save[15][15];
bool flag[15][15];
struct Point
{
   int x,y;
}pp[120];

int main()
{
   int r,c;

   while(scanf("%d%d",&r,&c)!=EOF)
   {
      int cnt=0;
      memset(flag,false,sizeof(flag));
      for(int i=1;i<=r;i++)
      {
         scanf("%s",save[i]+1);
         for(int j=1;j<=c;j++)
         {
            if(save[i][j]=='S')
            {
               pp[++cnt].x=i;
               pp[cnt].y=j;
            }
         }
      }
      for(int i=1;i<=r;i++) //掃描每一行
      {
         bool ff=true;
         for(int j=1;j<=c;j++) //如果都沒有S,則標記這一行
            if(save[i][j]=='S')
            {
               ff=false;
               break;
            }
         if(ff)
            memset(flag[i],true,sizeof(flag[i]));//表示能收
      }
      for(int i=1;i<=c;i++) //掃描每一列
      {
         bool ff=true;
         for(int j=1;j<=r;j++)
            if(save[j][i]=='S')
            {
               ff=false;
               break;
            }
         if(ff)
            for(int j=1;j<=r;j++) //標記這一列
               flag[j][i]=true;
      }

      int ans=0;
      for(int i=1;i<=r;i++)
         for(int j=1;j<=c;j++)
            if(flag[i][j]) //統計計數
               ans++;
      printf("%d\n",ans);
   }
   return 0;
}

B. Road Construction
題目意思:

給一些不能連接的邊,讓你構造一幅圖,使任意兩點能互相到達,且經過的邊數不超過2。

解題思路:

任意兩個點之間的邊數不超過2,說明該圖一定是星圖。找到中心的那個點(沒有限制的邊連接這點),直接連線即可。

代碼:


[cpp]
<SPAN style="FONT-SIZE: 18px">#include<iostream> 
#include<cmath>  
#include<cstdio>  
#include<cstdlib>  
#include<string>  
#include<cstring>  
#include<algorithm>  
#include<vector>  
#include<map>  
#include<set>  
#include<stack>  
#include<list>  
#include<queue>  
#define eps 1e-6  
#define INF 0x1f1f1f1f  
#define PI acos(-1.0)  
#define ll __int64  
#define lson l,m,(rt<<1)  
#define rson m+1,r,(rt<<1)|1  
using namespace std; 
 
/*
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
*/ 
int num[1100]; 
 
int main() 

   int n,m; 
 
   while(scanf("%d%d",&n,&m)!=EOF) 
   { 
      int a,b; 
 
      memset(num,0,sizeof(num)); 
      for(int i=1;i<=m;i++) //num[i]表示i點的度數  
      { 
         scanf("%d%d",&a,&b); 
         num[a]++,num[b]++; 
      } 
      int M=0; 
      num[0]=INF; 
      for(int i=1;i<=n;i++) 
         if(num[i]<num[M]) //找到度數為零的點  
            M=i; 
      printf("%d\n",n-1); 
      for(int i=1;i<=n;i++) 
      { 
         if(i==M) 
            continue; 
         printf("%d %d\n",i,M); //連接即可  
      } 
   } 
   return 0; 

 
</SPAN> 

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#define eps 1e-6
#define INF 0x1f1f1f1f
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
using namespace std;

/*
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
*/
int num[1100];

int main()
{
   int n,m;

   while(scanf("%d%d",&n,&m)!=EOF)
   {
      int a,b;

      memset(num,0,sizeof(num));
      for(int i=1;i<=m;i++) //num[i]表示i點的度數
      {
         scanf("%d%d",&a,&b);
         num[a]++,num[b]++;
      }
      int M=0;
      num[0]=INF;
      for(int i=1;i<=n;i++)
         if(num[i]<num[M]) //找到度數為零的點
            M=i;
      printf("%d\n",n-1);
      for(int i=1;i<=n;i++)
      {
         if(i==M)
            continue;
         printf("%d %d\n",i,M); //連接即可
      }
   }
   return 0;
}


C. Purification


題目意思:

給n*n的矩陣,讓你放最少數量的清洗劑,使得所有的點都能清洗到,清洗劑所放位置的那一行和那一列的所有點都能清洗,其中E點不能放清洗劑。

解題思路:

如果能放,一定為n個,因為每一行或每一列都要掃描到。

如果每一行都有可放的位置,則輸出每一行的任意一個能放的點即可,這樣每一行的點都會清洗到。

如果每一列都有可放的位置,則輸出每一列的任意一個能放得點即可,這樣每一列的都會清洗到,也就達到了要求。

代碼:


[cpp]
<SPAN style="FONT-SIZE: 18px">#include<iostream> 
#include<cmath>  
#include<cstdio>  
#include<cstdlib>  
#include<string>  
#include<cstring>  
#include<algorithm>  
#include<vector>  
#include<map>  
#include<set>  
#include<stack>  
#include<list>  
#include<queue>  
#define eps 1e-6  
#define INF 0x1f1f1f1f  
#define PI acos(-1.0)  
#define ll __int64  
#define lson l,m,(rt<<1)  
#define rson m+1,r,(rt<<1)|1  
using namespace std; 
 
/*
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
*/ 
 
bool rr[120],cc[120]; 
char save[120][120]; 
vector<int>row[120]; 
vector<int>col[120]; 
 
int main() 

   int n; 
 
   while(scanf("%d",&n)!=EOF) 
   { 
      memset(rr,false,sizeof(rr)); 
      memset(cc,false,sizeof(cc)); 
      for(int i=1;i<=n;i++) 
      { 
         row[i].clear(); 
         col[i].clear(); 
      } 
      for(int i=1;i<=n;i++) 
      { 
         scanf("%s",save[i]+1); 
         for(int j=1;j<=n;j++) 
         { 
            if(save[i][j]=='.') 
            { 
               rr[i]=true,cc[j]=true; //當前行和列能掃描到  
               row[i].push_back(j); 
               col[j].push_back(i); 
            } 
         } 
      } 
      bool r=true,c=true; //是否所有的行或列能掃描到  
 
      for(int i=1;i<=n;i++) 
         if(!rr[i]) 
         { 
             r=false; 
             break; 
         } 
      for(int i=1;i<=n;i++) 
         if(!cc[i]) 
         { 
            c=false; 
            break; 
         } 
      if(!r&&!c) //行或列都掃描不到  
      { 
         printf("-1\n"); 
         continue; 
      } 
      if(r) //如果行都能掃描到,直接輸出每一行的第一個可以放的位置  
      { 
         for(int i=1;i<=n;i++) 
            printf("%d %d\n",i,row[i][0]); 
         continue; 
      } 
      if(c) //對於列 同理  
      { 
         for(int i=1;i<=n;i++) 
            printf("%d %d\n",col[i][0],i); 
         continue; 
      } 
 
   } 
 
   return 0; 

 
 
</SPAN> 

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#define eps 1e-6
#define INF 0x1f1f1f1f
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
using namespace std;

/*
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
*/

bool rr[120],cc[120];
char save[120][120];
vector<int>row[120];
vector<int>col[120];

int main()
{
   int n;

   while(scanf("%d",&n)!=EOF)
   {
      memset(rr,false,sizeof(rr));
      memset(cc,false,sizeof(cc));
      for(int i=1;i<=n;i++)
      {
         row[i].clear();
         col[i].clear();
      }
      for(int i=1;i<=n;i++)
      {
         scanf("%s",save[i]+1);
         for(int j=1;j<=n;j++)
         {
            if(save[i][j]=='.')
            {
               rr[i]=true,cc[j]=true; //當前行和列能掃描到
               row[i].push_back(j);
               col[j].push_back(i);
            }
         }
      }
      bool r=true,c=true; //是否所有的行或列能掃描到

      for(int i=1;i<=n;i++)
         if(!rr[i])
         {
             r=false;
             break;
         }
      for(int i=1;i<=n;i++)
         if(!cc[i])
         {
            c=false;
            break;
         }
      if(!r&&!c) //行或列都掃描不到
      {
         printf("-1\n");
         continue;
      }
      if(r) //如果行都能掃描到,直接輸出每一行的第一個可以放的位置
      {
         for(int i=1;i<=n;i++)
            printf("%d %d\n",i,row[i][0]);
         continue;
      }
      if(c) //對於列 同理
      {
         for(int i=1;i<=n;i++)
            printf("%d %d\n",col[i][0],i);
         continue;
      }

   }

   return 0;
}

 

D. Biridian Forest


題目意思:

給一個n*m的矩陣,一個起始點和終點,矩陣中的數字表示該位置的魔鬼數量,當從起點到終點選擇一條路徑時,如果魔鬼能夠在人之前或同時到達該路徑某一位置,則人和魔鬼要打仗,選擇一條路徑,使得人與魔鬼打仗的個數最少。

解題思路:

該題主要是思維轉換。bfs+貪心

假設人當前選擇了一條路徑C->D,終點為D,某處魔鬼B 能夠和人C打仗,假設魔鬼在A位置與人打仗,則dis(B,A)<=dis(C,A)   =>dis(B,A,D)<=dis(C,D)   如果選擇D終點,只需使得Min(dis(B,D))<=dis(C,D)   而dis(B,A,D)>=Min(dis(B,D))  所以對於某一特定路徑,選擇終點D打仗比其他任何一點都好。

如果選擇從C-D的最短路,則能夠打仗的魔鬼數量就最少。

代碼:


[cpp]
<SPAN style="FONT-SIZE: 18px">#include<iostream> 
#include<cmath>  
#include<cstdio>  
#include<cstdlib>  
#include<string>  
#include<cstring>  
#include<algorithm>  
#include<vector>  
#include<map>  
#include<set>  
#include<stack>  
#include<list>  
#include<queue>  
#define eps 1e-6  
#define INF 0x1f1f1f1f  
#define PI acos(-1.0)  
#define ll __int64  
#define lson l,m,(rt<<1)  
#define rson m+1,r,(rt<<1)|1  
using namespace std; 
 
/*
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
*/ 
 
int dp[1100][1100],n,m; 
char save[1100][1100]; 
bool vis[1100][1100]; 
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}}; 
 
struct PP 

   int x,y; 
}; 
PP s,e; 
 
void bfs() //找到終點到任何一點的最短距離  

   queue<PP>myq; 
   myq.push(e); 
 
   while(!myq.empty()) 
   { 
      PP f=myq.front(); 
      myq.pop(); 
 
      for(int i=0;i<4;i++) 
      { 
         int xx=f.x+dir[i][0],yy=f.y+dir[i][1]; 
 
         if((save[xx][yy]=='S'||(save[xx][yy]>='0'&&save[xx][yy]<='9'))&&!vis[xx][yy]) 
         { 
            //printf(":%d %d\n",xx,yy);  
            vis[xx][yy]=true; 
            dp[xx][yy]=dp[f.x][f.y]+1; 
            myq.push((PP){xx,yy}); 
         } //不在方格裡的點為空的,不會掃描的  
      } 
   } 
   return ; 

 
int main() 

   while(scanf("%d%d",&n,&m)!=EOF) 
   { 
      memset(vis,false,sizeof(vis)); 
      for(int i=1;i<=n;i++) 
      { 
         scanf("%s",save[i]+1); 
         for(int j=1;j<=m;j++) 
         { 
            if(save[i][j]=='S') 
               s.x=i,s.y=j; 
            if(save[i][j]=='E') 
               e.x=i,e.y=j,dp[i][j]=0,vis[i][j]=true; 
         } 
      } 
     // printf("%d %d\n",e.x,e.y);  
      bfs(); 
      int ans=0; 
     // printf("%d\n",dp[s.x][s.y]);  
      for(int i=1;i<=n;i++) //最短距離小的話,就直接加上  
         for(int j=1;j<=m;j++) 
            if(save[i][j]>'0'&&save[i][j]<='9'&&vis[i][j]&&dp[i][j]<=dp[s.x][s.y]) 
               ans+=save[i][j]-'0'; 
      printf("%d\n",ans); 
 
 
 
   } 
 
   return 0; 

 
 
</SPAN> 

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#define eps 1e-6
#define INF 0x1f1f1f1f
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
using namespace std;

/*
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
*/

int dp[1100][1100],n,m;
char save[1100][1100];
bool vis[1100][1100];
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};

struct PP
{
   int x,y;
};
PP s,e;

void bfs() //找到終點到任何一點的最短距離
{
   queue<PP>myq;
   myq.push(e);

   while(!myq.empty())
   {
      PP f=myq.front();
      myq.pop();

      for(int i=0;i<4;i++)
      {
         int xx=f.x+dir[i][0],yy=f.y+dir[i][1];

         if((save[xx][yy]=='S'||(save[xx][yy]>='0'&&save[xx][yy]<='9'))&&!vis[xx][yy])
         {
            //printf(":%d %d\n",xx,yy);
            vis[xx][yy]=true;
            dp[xx][yy]=dp[f.x][f.y]+1;
            myq.push((PP){xx,yy});
         } //不在方格裡的點為空的,不會掃描的
      }
   }
   return ;
}

int main()
{
   while(scanf("%d%d",&n,&m)!=EOF)
   {
      memset(vis,false,sizeof(vis));
      for(int i=1;i<=n;i++)
      {
         scanf("%s",save[i]+1);
         for(int j=1;j<=m;j++)
         {
            if(save[i][j]=='S')
               s.x=i,s.y=j;
            if(save[i][j]=='E')
               e.x=i,e.y=j,dp[i][j]=0,vis[i][j]=true;
         }
      }
     // printf("%d %d\n",e.x,e.y);
      bfs();
      int ans=0;
     // printf("%d\n",dp[s.x][s.y]);
      for(int i=1;i<=n;i++) //最短距離小的話,就直接加上
         for(int j=1;j<=m;j++)
            if(save[i][j]>'0'&&save[i][j]<='9'&&vis[i][j]&&dp[i][j]<=dp[s.x][s.y])
               ans+=save[i][j]-'0';
      printf("%d\n",ans);

 

   }

   return 0;
}

 

 

E. Graph Reconstruction


題目意思:

給一幅圖,圖中任意結點的度數至多為2。

讓你重構一幅圖,要求:圖中節點和原來一樣,邊數數量也一樣,任意節點度數至多為2.

解題思路:

題中所說的圖的邊數最多為n.

1、隨機算法。

隨機m個點,連成m條邊,判斷每一條邊是否在給定的圖裡面,在的話,在隨機,都不在,則滿足題目要求,直接輸出就行了。

2、構造法。

當n<=7,直接暴力判斷

當n>7,一定存在一種構造滿足題意。

構造方法:

因為每個點的度數最多為2,所以每一個聯通塊要麼是一條線,要麼是一個環,首先根據聯通塊將節點分成若干部分。

然後將每一部分的節點的奇數位置節點提前。(保證相同部分的相鄰節點之間的連線不沖突)

然後選擇一個節點數量最多的那個部分,如果其節點數為偶數的話,交換頭兩個節點(防止環的情況尾和首相連有沖突),最後將其余各部分的節點從前之後依次插入。

最後按照給定的邊數,從前之後輸出相鄰的兩個節點構成一條邊,如果需要把最後一個節點和第一個節點連起來。

代碼:


[cpp]
<SPAN style="FONT-SIZE: 18px">#include<iostream> 
#include<cmath>  
#include<time.h>  
#include<cstdio>  
#include<cstdlib>  
#include<string>  
#include<cstring>  
#include<algorithm>  
#include<vector>  
#include<map>  
#include<set>  
#include<stack>  
#include<list>  
#include<queue>  
#define eps 1e-6  
#define INF 0x1f1f1f1f  
#define PI acos(-1.0)  
#define ll __int64  
#define lson l,m,(rt<<1)  
#define rson m+1,r,(rt<<1)|1  
using namespace std; 
 
/*
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
*/ 
vector<int>myv; 
vector<int>vv[110000]; 
int n,m; 
 
int main() 

   srand((unsigned)(time(NULL))); 
   while(scanf("%d%d",&n,&m)!=EOF) 
   { 
      int a,b; 
      myv.clear(); 
 
      for(int i=1;i<=n;i++) 
      { 
         vv[i].clear(); 
         myv.push_back(i); 
      } 
 
      for(int i=1;i<=m;i++) 
      { 
         scanf("%d%d",&a,&b); 
         vv[a].push_back(b); 
         vv[b].push_back(a); 
      } 
 
      bool tt=false; 
      for(int i=1;i<=500;i++) //隨機次數  
      { 
         random_shuffle(myv.begin(),myv.end()); //隨機節點  
         bool flag=true; 
 
         for(int j=0;j<m&&flag;j++) //看是否滿足  
         { 
            int a=myv[j]; 
            int b=myv[(j+1)%n]; 
 
            for(int k=0;k<vv[a].size();k++) 
               if(b==vv[a][k]) 
                  flag=false; 
         } 
         if(flag) //滿足的話,直接輸出  
         { 
            for(int j=0;j<m;j++) 
               printf("%d %d\n",myv[j],myv[(j+1)%n]); 
            tt=true; 
            break; 
         } 
 
      } 
      if(!tt) 
         printf("-1\n"); 
   } 
 
   return 0; 

 
</SPAN> 

#include<iostream>
#include<cmath>
#include<time.h>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#define eps 1e-6
#define INF 0x1f1f1f1f
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
using namespace std;

/*
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
*/
vector<int>myv;
vector<int>vv[110000];
int n,m;

int main()
{
   srand((unsigned)(time(NULL)));
   while(scanf("%d%d",&n,&m)!=EOF)
   {
      int a,b;
      myv.clear();

      for(int i=1;i<=n;i++)
      {
         vv[i].clear();
         myv.push_back(i);
      }

      for(int i=1;i<=m;i++)
      {
         scanf("%d%d",&a,&b);
         vv[a].push_back(b);
         vv[b].push_back(a);
      }

      bool tt=false;
      for(int i=1;i<=500;i++) //隨機次數
      {
         random_shuffle(myv.begin(),myv.end()); //隨機節點
         bool flag=true;

         for(int j=0;j<m&&flag;j++) //看是否滿足
         {
            int a=myv[j];
            int b=myv[(j+1)%n];

            for(int k=0;k<vv[a].size();k++)
               if(b==vv[a][k])
                  flag=false;
         }
         if(flag) //滿足的話,直接輸出
         {
            for(int j=0;j<m;j++)
               printf("%d %d\n",myv[j],myv[(j+1)%n]);
            tt=true;
            break;
         }

      }
      if(!tt)
         printf("-1\n");
   }

   return 0;
}

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved