Codeforces Round #192 (Div. 2)

题目地址: http://codeforces.com/contest/330


这套题目都不难,主要看思维和反应能力


第一题:水题

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;

typedef long long LL;
const int N=66;
const LL II=100000000;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);

char s[12][12];
int vis[12][12];

int main()
{
    int i,j,T;
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(vis,0,sizeof(vis));
        for(i=0;i<n;i++)
            scanf("%s",s[i]);
        int sum=0;
        for(i=0;i<n;i++)
        {
            int flag=0;
            for(j=0;j<m;j++)
                if(s[i][j]=='S')
                {
                    flag=1;break;
                }
            if(flag==0)
            {
                for(j=0;j<m;j++)
                {
                    if(s[i][j]=='.')
                        sum++;
                    s[i][j]='x';
                }
            }
        }

        for(j=0;j<m;j++)
        {
            int flag=0;
            for(i=0;i<n;i++)
                if(s[i][j]=='S')
                {
                    flag=1;break;
                }
            if(flag==0)
            {
                for(i=0;i<n;i++)
                {
                    if(s[i][j]=='.')
                        sum++;
                    s[i][j]='x';
                }
            }
        }
        printf("%d
",sum);
    }
    return 0;
}


第二题:

由于题目给出了这个条件.开始的时候没注意,看了别人做的那么快,又看了一遍题目,果断发现之,

m<n/2,所以至少有一个点没有出现在上面,所以将所有的点与这个没有出现的点连起来即为答案。

开始的时候傻了10^3我开了111的数组,果断错了一次,哎……

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;


int k[1111];

int main()
{
    int i,j,n,m,flag,sum;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(k,0,sizeof(k));
        for(i=0;i<m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            k[a]=k[b]=1;
        }
        int t;
        for(i=1;i<=n;i++)
        {
            if(k[i]==0)
            {
                t=i;
                break;
            }
        }
        printf("%d
",n-1);
        for(i=1;i<=n;i++)
        {
            if(i==t)    continue;
            printf("%d %d
",t,i);
        }
    }
    return 0;
}


第三题:求每一行或每一列是不是都出现"."即可,因为至少是n个点

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;

char s[111][111];
int p[111][111];
int sum,n;

int main()
{
    int i,j,m,flag;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=1;i<=n;i++)
            scanf("%s",s[i]+1);
        int sum1=0,sum2=0;
        for(i=1;i<=n;i++)
        {
            flag=0;
            for(j=1;j<=n;j++)
                if(s[i][j]=='.')
                {
                    flag=1;break;
                }
            if(flag)
                sum1++;
        }

        for(j=1;j<=n;j++)
        {
            flag=0;
            for(i=1;i<=n;i++)
                if(s[i][j]=='.')
                {
                    flag=1;break;
                }
            if(flag)
                sum2++;
        }
        if(sum1!=n&&sum2!=n)
        {
            printf("-1
");
            continue;
        }

        if(sum1==n)
        {
            for(i=1;i<=n;i++)
            {
                for(j=1;j<=n;j++)
                    if(s[i][j]=='.')
                    {
                        printf("%d %d
",i,j);break;
                    }
            }
            continue;
        }

        if(sum2==n)
        {
            for(j=1;j<=n;j++)
            {
                for(i=1;i<=n;i++)
                    if(s[i][j]=='.')
                    {
                        printf("%d %d
",i,j);break;
                    }
            }
            continue;
        }
    }
    return 0;
}


第四题:给你一个地图,E代表出口,S代表你自己,T代表树不能经过,数字类比代表在这个地方有t个怪兽,

你和怪兽每一秒都可以移动,想要经过怪兽必须将其杀死,问你用最短的时间达到出口最多要打败多少个怪兽。

思路:从出口开始搜索,搜索到人最少步数,在这个步数内(包括),能有多少个怪兽也能达到出口,即为答案。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;

typedef __int64 LL;
const int N=1005;
const LL II=1000000007;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);

int n,m,bx,by,ex,ey;
bool vis[N][N];
char maps[1005][1005];
int t[4][2]={1,0,-1,0,0,1,0,-1};
int Max;

struct xh
{
    int x,y;
    int step;
}w,e;

void bfs()
{
    int i,j,sum=0;
    memset(vis,0,sizeof(vis));
    vis[bx][by]=1;
    queue<xh> q;
    w.step=0;w.x=bx;w.y=by;
    q.push(w);
    while(!q.empty())
    {
        e=q.front();
        q.pop();
        if(e.step>=Max)//这个地方是即将要加上的,所以是大于等于
        {
            break;
        }

        for(i=0;i<4;i++)
        {
            w=e;
            int x=w.x+t[i][0],y=w.y+t[i][1];
            if(x>=0&&x<n&&y>=0&&y<m&&maps[x][y]!='T'&&vis[x][y]==0)
            {
                vis[x][y]=1;
                w.step+=1;
                w.x=x;  w.y=y;
                if(maps[x][y]=='S')
                    Max=w.step;
                else
                    sum+=(maps[x][y]-'0');
                q.push(w);
            }
        }
    }
    printf("%d
",sum);
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int i,j;
        for(i=0;i<n;i++)
        {
            scanf("%s",maps[i]);
            for(j=0;j<m;j++)
                if(maps[i][j]=='E')
                {
                    bx=i;by=j;
                }
                else if(maps[i][j]=='S')
                {
                    ex=i;ey=j;
                }
        }
        Max=INF;
        bfs();
    }
    return 0;
}


第五题:给一幅图,图中任意结点的度数至多为2。
让你重构一幅图,要求:图中节点和原来一样,边数数量也一样,任意节点度数至多为2.

思路:随机算法,随机m个点,连成m条边,判断每一条边是否在给定的图里面,在的话,继续随机,都不在,则满足题目要求,直接输出。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;

typedef __int64 LL;
const int N=100005;
const LL II=1000000007;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);

int n,m,ans;
int a[N];
vector<int> v[N];

void ACMer_xiaohao()
{
    int i,j,k;
    int tmp=0,flag=0;
    for(i=1;i<=500;i++)//随机500次
    {
        int ok=1;
        random_shuffle(a+1,a+n+1);
        for(j=1;j<=m;j++)
        {
            int si=v[a[j]].size();
            for(k=0;k<si;k++)
            {
                if(j==n)    tmp=1;
                else    tmp=j+1;
                if(v[a[j]][k]==a[tmp])
                {
                    ok=0;
                    break;
                }
            }
        }
        if(ok)
        {
            flag=1;
            for(j=1;j<=m;j++)
            {
                if(j==n)    tmp=1;
                else    tmp=j+1;
                printf("%d %d
",a[j],a[tmp]);
            }
            break;
        }
    }
    if(!flag)
        printf("-1
");
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int i,j,c,b;
        for(i=1;i<=n;i++)
        {
            v[i].clear();//每次清除
            a[i]=i;
        }
        for(i=1;i<=m;i++)
        {
            scanf("%d%d",&c,&b);
            v[c].push_back(b);
            v[b].push_back(c);
        }
        ACMer_xiaohao();
    }
    return 0;
}


原文地址:https://www.cnblogs.com/jiangu66/p/3211860.html