『比赛』Codeforces Round #369 (Div. 2) 5题总结

题目链接:http://codeforces.com/contests

A. Bus to Udayland

分析:就是一个手速的贪心题,看懂英文就好了…

/* Author:GavinjouElephant
 * Title:
 * Number:
 * main meanning:
 *
 *
 *
 */


#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1005;
int Scan()//读入整数外挂.
{
    int res = 0, ch, flag = 0;

    if((ch = getchar()) == '-')             //判断正负
        flag = 1;

    else if(ch >= '0' && ch <= '9')           //得到完整的数
        res = ch - '0';
    while((ch = getchar()) >= '0' && ch <= '9' )
        res = res * 10 + ch - '0';
    return flag ? -res : res;
}
 void Out(int a)    //输出外挂
 {
     if(a>9)
         Out(a/10);
     putchar(a%10+'0');
 }

char seat[maxn][10];
int n;
int main()
{
#ifndef ONLINE_JUDGE
    freopen("coco.txt","r",stdin);
    freopen("lala.txt","w",stdout);
#endif
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%s",seat[i]);
    }
    bool flag=true;
    for(int i=0;i<n;i++)
    {
        if(seat[i][0]=='O'&&seat[i][1]=='O')
        {
              flag=false;
              seat[i][0]=seat[i][1]='+';
              break;
        }
        if(seat[i][3]=='O'&&seat[i][4]=='O')
        {
              flag=false;
              seat[i][3]=seat[i][4]='+';
              break;
        }

    }

    if(flag) printf("NO\n");
    else
    {
        printf("YES\n");
        for(int i=0;i<n;i++) printf("%s\n",seat[i]);
    }
    return 0;
}

B. Chris and Magic Square

分析:这是一道模拟题,看样例就知道,就是跟你一个阵,里面有一个位置是空的(0),然后让你填入一个>0的数,
使得行之和,列之和,对角线之和都相等. 这是一道模拟题,很简单…,按着题意写就行了

/* Author:GavinjouElephant
 * Title:
 * Number:
 * main meanning:
 *
 *
 *
 */


#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
int Scan()//读入整数外挂.
{
    int res = 0, ch, flag = 0;

    if((ch = getchar()) == '-')             //判断正负
        flag = 1;

    else if(ch >= '0' && ch <= '9')           //得到完整的数
        res = ch - '0';
    while((ch = getchar()) >= '0' && ch <= '9' )
        res = res * 10 + ch - '0';
    return flag ? -res : res;
}
 void Out(int a)    //输出外挂
 {
     if(a>9)
         Out(a/10);
     putchar(a%10+'0');
 }

 int a[505][505];
 ll rsum[505];
 ll lsum[505];
 ll lx;
 ll rx;
 int n;
 ll M;
 int si,sj;
 void solve()
 {
     if(n==0) {printf("1\n");return;}

     ll c=M-rsum[si];
     if(c<=0)  {printf("-1\n");return;}

     rsum[si]=M;

     lsum[sj]+=c;

     if((si+sj)==n)rx+=c;
     if(si==sj)lx+=c;

     if(lx!=rx||lx!=M){printf("-1\n");return;}

     for(int i=0;i<n;i++)
     {
         if(rsum[i]!=M){printf("-1\n");return;}
     }

     for(int j=0;j<n;j++)
     {
         if(lsum[j]!=M){printf("-1\n");return;}
     }
     printf("%I64d\n",c);
 }
int main()
{
#ifndef ONLINE_JUDGE
    freopen("coco.txt","r",stdin);
    freopen("lala.txt","w",stdout);
#endif
    scanf("%d",&n);
    n--;

    memset(rsum,0,sizeof(rsum));
    memset(lsum,0,sizeof(lsum));
    lx=0;
    rx=0;

    M=(long long)-INF;


    for(int i=0;i<=n;i++)
    {
        for(int j=0;j<=n;j++)
        {
            scanf("%d",&a[i][j]);
            if(a[i][j]==0){ si=i;sj=j;}

            rsum[i]+=a[i][j];
            lsum[j]+=a[i][j];

            if(i==j)lx+=a[i][j];
            if(i+j==n) rx+=a[i][j];
        }
        M=max(M,rsum[i]);
    }


    solve();




    return 0;
}

C. Coloring Trees

分析: 这道题扎眼一看就是个dp,我几乎没怎么想,我的代码那时坑在了边界值,忘记处理了,简直天煞,浪费了好多时间也没A掉, dp[i][j][k]:代表我当前所要染色的位置为i,我当前染了第j种颜色,k为连续的个数
这个dp很容易推,所以不多讲.

/* Author:GavinjouElephant
 * Title:
 * Number:
 * main meanning:
 *
 *
 *
 */


#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const ll INF=0x3f3f3f3f;
const ll maxn=(ll)100000000000+10;
ll Scan()//读入整数外挂.
{
    ll res = 0, ch, flag = 0;
    if((ch = getchar()) == '-')             //判断正负
        flag = 1;

    else if(ch >= '0' && ch <= '9')           //得到完整的数
        res = ch - '0';
    while((ch = getchar()) >= '0' && ch <= '9' )
        res = res * 10 + ch - '0';
    return flag ? -res : res;
}
void Out(ll a)    //输出外挂
{
    if(a>9)
        Out(a/10);
    putchar(a%10+'0');
}
ll n,m,k;
ll dp[105][105][105];//现在选择第i个,上一个选择是C,现在不同的长度是105.
ll p[105][105];

ll tree[105];

int main()
{
    scanf("%I64d%I64d%I64d",&n,&m,&k);
    for(ll i=0; i<=n; i++)
    {
        for(ll j=0; j<=m; j++)
        {
            for(ll K=0; K<=k; K++)
            {
                if(i==0&&K==0)
                {
                    dp[i][j][K]=0;
                    continue;
                }
                dp[i][j][K]=maxn;
            }
        }
    }
    for(ll i=1; i<=n; i++)
    {
        scanf("%I64d",&tree[i]);
    }
    for(ll i=1; i<=n; i++)
    {
        for(ll j=1; j<=m; j++)
        {
            scanf("%I64d",&p[i][j]);
        }
    }


    for(ll i=1; i<=n; i++)
    {
        for(ll t=1; t<=k; t++)
        {
            if(tree[i]==0)
            {
                for(ll se=1; se<=m; se++)
                {
                    if(i!=1)
                    {
                        for(ll lse=1; lse<=m; lse++)
                        {
                            if(se==lse) dp[i][se][t]=min(dp[i][se][t],p[i][se]+dp[i-1][lse][t]);
                            else   dp[i][se][t]=min(dp[i][se][t],p[i][se]+dp[i-1][lse][t-1]);
                        }
                    }
                    else
                    {
                        dp[i][se][t]=min(dp[i][se][t],p[i][se]+dp[i-1][0][t-1]);
                    }
                }

            }
            else
            {
                ll se=tree[i];
                if(i!=1)
                {
                    for(ll lse=1; lse<=m; lse++)
                    {
                        if(se==lse) dp[i][se][t]=min(dp[i][se][t],dp[i-1][lse][t]);
                        else   dp[i][se][t]=min(dp[i][se][t],dp[i-1][lse][t-1]);
                    }
                }
                else
                {
                     dp[i][se][t]=min(dp[i][se][t],dp[i-1][0][t-1]);

                }
            }
        }
    }
    ll ans=maxn;
    for(int i=1; i<=m; i++) ans=min(ans,dp[n][i][k]);
    if(ans>=maxn)printf("-1\n");
    else printf("%I64d\n",ans);

    return 0;
}

D. Directed Roads

题解:很水的强连通分量,可以很容易发现对于一个环n,那么破除这个环的总数有(2^N-2)种, 既然时n条边,而且每个点都只有1出度,那么我的想法就是只要破除了环,就可以了,假设有M个点,N个点为环最后答案为2^M *(2^N-2) 用乘法原理解决了 .
ps:如果我没卡上面那题就好了…

/* Author:GavinjouElephant
 * Title:
 * Number:
 * main meanning:
 *
 *
 *
 */


#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=2e5+10;
const ll mod=1e9+7;
int Scan()//读入整数外挂.
{
    int res = 0, ch, flag = 0;

    if((ch = getchar()) == '-')             //判断正负
        flag = 1;

    else if(ch >= '0' && ch <= '9')           //得到完整的数
        res = ch - '0';
    while((ch = getchar()) >= '0' && ch <= '9' )
        res = res * 10 + ch - '0';
    return flag ? -res : res;
}
 void Out(int a)    //输出外挂
 {
     if(a>9)
         Out(a/10);
     putchar(a%10+'0');
 }

 int V;
 vector<int> G[maxn];
 vector<int> rG[maxn];
 vector<int> vs;

 bool used[maxn];
 int cmp[maxn];
 int cnt_cmp[maxn];
 int Sum;
 void add_edge(int from ,int to)
 {
     G[from].push_back(to);
     rG[to].push_back(from);
 }

 void dfs(int v)
 {
     used[v]=true;
     for(int i=0;i<G[v].size();i++)
     {
         if(!used[G[v][i]]) dfs(G[v][i]);
     }
     vs.push_back(v);
 }

 void rdfs(int v,int k)
 {
     Sum++;
     used[v]=true;
     cmp[v]=k;
     for(int i=0;i<rG[v].size();i++)
     {
         if(!used[rG[v][i]]) rdfs(rG[v][i],k);
     }
 }

 int scc()
 {
     memset(used,0,sizeof(used));
     vs.clear();
     for(int v=0;v<V;v++)
     {
         if(!used[v]) dfs(v);
     }
     memset(used,0,sizeof(used));

     int k=0;

     for(int i=vs.size()-1;i>=0;i--)
     {

         if(!used[vs[i]])
         {
             Sum=0;
             rdfs(vs[i],k);
             cnt_cmp[k++]=Sum;
         }
     }
     return k;
 }
 ll qmod(ll a,ll n)
 {
     ll res=1;
     while(n)
     {
         if(n&1)res=(res*a)%mod;
         a=(a*a)%mod;
         n>>=1;
     }
     return res%mod;
 }
 ll qmul(ll a,ll n)
 {
      ll res=0;
      while(n)
      {
          if(n&1)res=(res+a)%mod;
          a=(a+a)%mod;
          n>>=1;
      }
      return res%mod;

 }
int main()
{
#ifndef ONLINE_JUDGE
    freopen("coco.txt","r",stdin);
    freopen("lala.txt","w",stdout);
#endif
     int to;
     scanf("%d",&V);
     for(int i=0;i<V;i++)
     {
         scanf("%d",&to);
         to--;
         add_edge(i,to);
     }

     int K=scc();
     ll ans=1;
     for(int i=0;i<K;i++)
     {
         if(cnt_cmp[i]>1)
         {
             ll tmp=(qmod(2,(ll)cnt_cmp[i])-2+mod)%mod;
             ans=qmul(ans,tmp);
         }
         else  ans=qmul(ans,2)%mod;
     }
     printf("%I64d\n",ans);

    return 0;
}

E. ZS and The Birthday Paradox

分析:
转载:http://blog.csdn.net/acmore_xiong/article/details/52409248
这个讲得很清楚,我也不懂这个数论的知识,我看了才明白的.

/* Author:GavinjouElephant
 * Title:
 * Number:
 * main meanning:
 *
 *
 *
 */


#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const ll mod=1e6+3;
int Scan()//读入整数外挂.
{
    int res = 0, ch, flag = 0;

    if((ch = getchar()) == '-')             //判断正负
        flag = 1;

    else if(ch >= '0' && ch <= '9')           //得到完整的数
        res = ch - '0';
    while((ch = getchar()) >= '0' && ch <= '9' )
        res = res * 10 + ch - '0';
    return flag ? -res : res;
}
 void Out(int a)    //输出外挂
 {
     if(a>9)
         Out(a/10);
     putchar(a%10+'0');
 }
 ll n,k;
 ll qmod(ll a,ll b,ll MOD)
 {
      ll ret=1;
      while(b)
      {
          if(b&1)ret=(ret*a)%mod;
          a=(a*a)%mod;
          b>>=1;
      }
      return ret;
 }
int main()
{
#ifndef ONLINE_JUDGE
    freopen("coco.txt","r",stdin);
    freopen("lala.txt","w",stdout);
#endif

    scanf("%I64d%I64d",&n,&k);

    if(n<64&&(k>((1ll)<<n)))
    {
        printf("1 1\n");
        return 0;
    }
    ll t=0;
    for(ll i=2;i<=(k-1);i<<=1)
    {
        t+=(k-1)/i;
    }
    ll gcd=qmod(2,t,mod);
    ll x=qmod(2,n,mod);
    ll A,B;
    A=B=1;
    for(ll i=1;i<=(k-1);i++)
    {
        A=A*(x-i+mod)%mod;
        if(!A)break;
    }
    ll inv=qmod(gcd,mod-2,mod);

    A=A*inv%mod;
    B=qmod(x,k-1,mod);
    B=B*inv%mod;
    A=(B-A+mod)%mod;
    printf("%I64d %I64d\n",A,B);



    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值