关闭

Codeforces Round #369 (Div. 2) 题解

200人阅读 评论(0) 收藏 举报
分类:

【A. Bus to Udayland】http://www.codeforces.com/contest/711/problem/A

【题意】公交车上有些位置能做,有些不能坐,问是否有两个相邻的位置。

【解题方法】找到并排的2个0就行了。

【AC代码】

#include <bits/stdc++.h>
using namespace std;
int n;
char s[1010][10];
int main()
{
    cin>>n;
    for(int i=0; i<n; i++) cin>>s[i];
    bool flag=false;
    for(int i=0; i<n; i++)
    {
        if(s[i][0]=='O'&&s[i][1]=='O')
        {
            flag=true;
            s[i][0]=s[i][1]='+';
            break;
        }
        if(s[i][3]=='O'&&s[i][4]=='O')
        {
            flag=true;
            s[i][3]=s[i][4]='+';
            break;
        }
    }
    if(flag){
        puts("YES");
        for(int i=0; i<n; i++)printf("%s\n",s[i]);
    }
    else{
        puts("NO");
    }
}

【B. Chris and Magic Square】http://www.codeforces.com/contest/711/problem/B

【题意】一个n*n(n<=500)的矩形中有一个格子为空,问是否能填上某个数,使得每行每列以及主对角线之后均相等。

【解题方法】n=1特判。n>=2找出某个可能合法的解,填入后再验证一下。 数据范围爆int啦。

【AC 代码】

#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e5+10;
LL a[550][550];
LL row[550];
LL col[550];
set<LL>s;
int c,r;
int main()
{
    int n;
    cin>>n;
    s.clear();
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= n;j++){
            scanf("%I64d",&a[i][j]);
            if(a[i][j] == 0){
                r = i,c = j;
            }
        }
    }
    if(n == 1){
        printf("1\n");
        return 0;
    }
    LL sum = 0;
    for(int i = 1;i <= n;i++){
        if(i != r){
            for(int j = 0;j <= n;j++){
                sum += a[i][j];
            }
            break;
        }
    }
    for(int i  = 1;i <= n;i++){
        sum -= a[r][i];
    }
    a[r][c] = sum;
    LL sum1 = 0,sum2 = 0;
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= n;j++){
            col[i] += a[i][j];
            row[i] += a[j][i];
        }
        sum1 += a[i][i];
        sum2 += a[i][n-i+1];
    }
    s.insert(sum1);
    s.insert(sum2);
    for(int i = 1;i <= n;i++){
        s.insert(col[i]);
        s.insert(row[i]);
    }
    if(s.size() > 1){
        puts("-1");
    }
    else{
        if(sum>0) cout<<sum<<endl;
        else puts("-1");
    }
    return 0;
}

【C. Coloring Trees】http://www.codeforces.com/contest/711/problem/C

【题意】有n棵树排成一列,一共有m种颜料,有些树被涂了颜色,有些树没有。可以花费a[i][j]的代价给第i棵树涂上j的颜色。问给每棵树涂上颜色后,将树恰好分成k段的最小花费。(连续颜色相同的最长区间为一段)n,m,k<=100【解题方法】n^4的dp显而易见啦。好像有n^3的,不过n才100,谁便搞啦。

【AC 代码】O(n^4)

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL inf = 1e18;
const int maxn=110;
LL a[maxn],b[maxn][maxn],dp[maxn][maxn][maxn];
int n,m,k;
int main()
{
    cin>>n>>m>>k;
    for(int i=1; i<=n; i++) cin>>a[i];
    for(int i=1; i<=n; i++){
        for(int j=1; j<=m; j++){
            cin>>b[i][j];
        }
    }
    memset(dp,0x3f,sizeof(dp));
    if(!a[1]) for(int i=1; i<=m; i++) dp[1][i][1]=b[1][i];
    else dp[1][a[1]][1]=0;
    for(int i=1; i<n; i++){
        for(int j=1; j<=m; j++){
            for(int l=1; l<=k; l++){
                if(a[i+1]==0){
                    for(int r=1; r<=m; r++){
                        if(j==r) dp[i+1][r][l]=min(dp[i+1][r][l],dp[i][j][l]+b[i+1][r]);
                        else dp[i+1][r][l+1]=min(dp[i+1][r][l+1],dp[i][j][l]+b[i+1][r]);
                    }
                }
                else{
                    for(int r=1; r<=m; r++){
                        if(j==a[i+1]) dp[i+1][j][l]=min(dp[i+1][j][l],dp[i][j][l]);
                        else dp[i+1][a[i+1]][l+1]=min(dp[i+1][a[i+1]][l+1],dp[i][j][l]);
                    }
                }
            }
        }
    }
    LL ans=inf;
    for(int i=1; i<=m; i++){
        ans=min(ans,dp[n][i][k]);
    }
    if(ans==inf) ans=-1;
    printf("%I64d\n",ans);
    return 0;
}

【D. Directed Roads】http://www.codeforces.com/contest/711/problem/D

【题意】有n个点,给定一个数组a[i](≠i),表示有一条i-->a[i]的有向边。可以将某些有向边的方向翻转,因此共有2^n的方案。问这些方案中有多少种方案使得所形成的图不含有环。n<=2*10^5

【解题方法】由于一共只有n条边,整个图相当于被分成了若干个联通块,且每个联通块内有且只有一个环。若某个连通块中有i个点,存在一个点数为j的环,那么其对答案的贡献为2^(i-j) * (2^j-2)

【AC 代码】

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL mod = 1e9+7;
const int maxn = 2e5+5;
int p[maxn],c[maxn],clk[maxn];
LL powmod(int x)
{
    LL res=1;
    while(x--)
    {
        res<<=1;
        res%=mod;
    }
    return res;
}
int main()
{
    int n,cnt=0;
    cin>>n;
    for(int i=1; i<=n; i++) cin>>p[i];
    int num=n;
    LL ans=1;
    for(int i=1; i<=n; i++){
        if(!c[i])
        {
            c[i]=i;
            clk[i]=++cnt;
            int x=i;
            while(1)
            {
                x=p[x];
                if(c[x])
                {
                    if(c[x]==i){
                        int t=cnt-clk[x]+1;
                        ans=ans*(powmod(t)-2)%mod;
                        ans=ans%mod;
                        num-=t;
                    }
                    break;
                }
                else{
                    c[x]=i;
                    clk[x]=++cnt;
                }
            }
        }
    }
    ans=ans*powmod(num);
    ans%=mod;
    if(ans<0) ans+=mod;
    cout<<ans<<endl;
    return 0;
}

【E. ZS and The Birthday Paradox】点击打开链接

【题意】假设一年有2^n天,问k个小朋友中有两个小朋友生日相同的概率。假设该概率约分后为 p / q ,输出p , q对1000003取模的解。n , k <= 10^18。

【解题方法】参见http://www.cnblogs.com/rpSebastian/p/5821057.html

【解题方法】若k > 2^n 则答案为1 / 1 , 否则答案为 1 - A(2^n,k) / (2^n)^k ,可以发现分子与分母的gcd必定为2^i。计算A(2^n,k)=(2^n) * (2^n-1) * ... * (2^n-k+1)含多少个因子2,相当于计算0~k-1以及2^n。求出gcd后,就可以暴力计算分子,分母对p取模后的结果,再乘上gcd的逆元。

【AC 代码】

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod=1e6+3;
LL powmod(LL a,LL n)
{
    LL res=1;
    while(n)
    {
        if(n&1) res=res*a%mod;
        a=a*a%mod;
        n>>=1;
    }
    return res;
}
int main()
{
    LL n,k;
    scanf("%I64d%I64d",&n,&k);
    if(n<=62&&k>(1LL<<n)){
        printf("1 1\n");
        return 0;
    }
    //这里想了很久啊,悲伤
   LL num=0;
    for(LL i=k-1; i; i>>=1){
        num+=i/2;
    }
    //cout<<num<<endl;
    LL a=powmod(2,n),b=1;
    for(LL i=1; i<=k-1; i++)
    {
        LL temp=(a-i+mod)%mod;
        b=b*temp%mod;
        if(temp==0) break;
    }
    //cout<<b<<endl;
    //cout<<a<<" "<<b<<endl;
    LL inv=powmod(powmod(2,num),mod-2);
    a=powmod(a,k-1);
    a=a*inv%mod;
    b=b*inv%mod;
    b=(a-b+mod)%mod;
    printf("%I64d %I64d\n",b,a);
    return 0;
}


0
0
查看评论

Codeforces Round #369 (Div. 2) D. Directed Roads (dfs+组合数学 图论)

传送门:D. Directed Roads 描述: D. Directed Roads time limit per test 2 seconds memory limit per test 256 megabytes input standard i...
  • guhaiteng
  • guhaiteng
  • 2016-08-30 19:06
  • 373

解题报告:Codeforces Round #433 (Div. 2) E. Boredom ( 离线处理+树状数组)

题目链接 题意: n*n的矩阵,有n个不同行列的格子染色,染色的格子两两之间组成的矩阵定义为beautiful。 q组询问,每次给出一个矩阵,询问与它相交的beautiful的矩阵的数目 n,q 思路: 每次查询分成九个矩阵,只需要知道各个矩阵中的染色的点数,即可得出答案 其中...
  • qq_32570675
  • qq_32570675
  • 2017-09-07 09:56
  • 331

Codeforces Round #460 (Div. 2)题目题解

A.Supermarket (水题) #include #include #include #include #include using namespace std; int main() { int N,M; double ans = 99999999;...
  • wyxeainn
  • wyxeainn
  • 2018-01-31 23:17
  • 72

Codeforces Round #258 (Div. 2)-(A,B,C,D,E)

A:Game With Sticks 水题。。。每次操作,都会拿走一个横行,一个竖行。 所以一共会操作min(横行,竖行)次。 #include #include #include #include #include #include #include #include #pragma commen...
  • rowanhaoa
  • rowanhaoa
  • 2014-07-25 14:39
  • 1470

【解题报告】Codeforces Round #401 (Div. 2)

简略的解题报告。
  • TRiddle
  • TRiddle
  • 2017-02-25 17:55
  • 408

Codeforces Round #395 (Div. 2)(ABCD)

ps:打完这场cf才知道自己真的很菜,还是停留在AB题的水平,有时候CD其实很简单,但就是想不到,别人一眼看出而我就是想不到,有时候想到了点子上但就是突破不了 题目链接:  Codeforces Round #395 (Div. 2) A题: &...
  • qq_34731703
  • qq_34731703
  • 2017-02-03 12:50
  • 486

Codeforces Round #304 (Div. 2) A,B,C题解

A. Soldier and Bananas time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output A soldi...
  • qq_24489717
  • qq_24489717
  • 2015-05-27 13:48
  • 999

Codeforces Round #256 (Div. 2) E. Divisors

E. Divisors time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output ...
  • modiz
  • modiz
  • 2014-07-18 23:37
  • 586

Codeforces Round #456 (Div. 2) D. Fishes

D. Fishes time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output While Grisha was celebrat...
  • Haipai1998
  • Haipai1998
  • 2018-01-20 14:06
  • 34

Codeforces Round #451 (Div. 2)题解

比赛时间2017 12 16 19:35-21:35。 结果+133rating。
  • s223568907
  • s223568907
  • 2017-12-17 13:19
  • 75
    个人资料
    • 访问:409216次
    • 积分:16447
    • 等级:
    • 排名:第747名
    • 原创:1274篇
    • 转载:18篇
    • 译文:0篇
    • 评论:61条
    博客专栏
    文章分类