1.20 Codeforces570 div2练习

A题
题意:
有n个候选人,m个城市,每个城市选出一个得票最多的候选人,然后在选出的这些候选人中,再选出一个得票最多的。关键是如果得票相同,选择编号小的。
题目的坑:

  1. 如果一个城市里都是0票,那么选1号候选人
  2. 如果有多个高票候选人的票数相同,要从号小的里选

代码

#include <bits/stdc++.h>
using namespace std;
int n,m;
int a[101][101];
int f[101];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)
        for(int j=1;j<=n;j++)
    {
        cin>>a[i][j];
    }
    int mx;
    int cnt=0;
    int col=0;
    for(int i=1;i<=m;i++)
    {
        mx=0;
        col=0;
        for(int j=1;j<=n;j++)
        {
           if(a[i][j]>mx)
           {
               mx=a[i][j];
               col=j;
           }
        }
        if(col!=0)
        f[col]++;
        else // 如果都是0,选第一个
            f[1]++;
    }
    mx=0;
    for(int i=1;i<=n;i++)
    {
        if(f[i]>mx)
        {
            cnt=i;
            mx=f[i];
        }
    }
    if(!cnt) // 如果没有,选第一个
    {
        cout<<1<<endl;
        return 0 ;
    }

    cout<<cnt<<endl;
}

B题

1~n个数,甲先选一个数m,乙再选一个数x,当且仅当乙选的数到1-n中随机出现的数c的距离,比甲选的数到c 的距离近,乙才获胜。
即|c-m| > |c-x|
已知n 和 m,求一个获胜概率最大的x.

分析:从题意知道,不能选m,因为相同概率甲也赢。那么只要比甲概率大,那么就可以赢。c的分布有三种可能:

  1. 等于m 无论如何都是甲赢
  2. 小于m
  3. 大于m
    第一种可能不做考虑,第二种可能只要选m-1即可,第三种可能只要选m+1即可。
    因此下面只需要对m-1 和,m+1 这两种情况进行讨论,判断哪一个区间在这里插入代码片大一些。

代码:

#include<bits/stdc++.h>
using namespace std;
int n,m;
//int mp[101][101];
int main()
{
    cin>>n>>m;
   // cout<<(n+1)/2<<endl;
    int a=m-1;
    int b=m+1;
    if(n==1&&m==1)
        {
            printf("1\n");
            return 0;
        }


    if(a>=n-b+1)
        cout<<a<<endl;
    else
        cout<<b<<endl;

}

C题
题意:
给出一个一个字符串,给出一种操作:将字符串中连续的两个点’…’ 换成一个点’.’,给出一种替换,将指定的第几个字符替换成字母或者点。

Input
10 3
.b..bz....
1 h
3 c
9 f
Output
4
3
1
Input
4 4
.cc.
2 .
3 .
2 a
1 a
Output
1
3
1
1
Note
Note to the first sample test (replaced periods are enclosed in square brackets).

The original string is ".b..bz....".

after the first query f(hb..bz....) = 4    ("hb[..]bz...."  →  "hb.bz[..].."  →  "hb.bz[..]."  →  "hb.bz[..]"  →  "hb.bz.")
after the second query f(hbс.bz....) = 3    ("hbс.bz[..].."  →  "hbс.bz[..]."  →  "hbс.bz[..]"  →  "hbс.bz.")
after the third query f(hbс.bz..f.) = 1    ("hbс.bz[..]f."  →  "hbс.bz.f.")
Note to the second sample test.

The original string is ".cc.".

after the first query: f(..c.) = 1    ("[..]c."  →  ".c.")
after the second query: f(....) = 3    ("[..].."  →  "[..]."  →  "[..]"  →  ".")
after the third query: f(.a..) = 1    (".a[..]"  →  ".a.")
after the fourth query: f(aa..) = 1    ("aa[..]"  →  "aa.")

分析:
这个题其实就是一个模拟,首先计算源字符串操作数,即连续点个数减一。
接着,如果字符换字符,点换点,对结果没有影响,
如果用字母换点,如果前后都有点,结果-2,有一个-1,否则不变
如果用点换字母,如果前后都有点,结果+2,有一个+1,否则不变

#include <bits/stdc++.h>
using namespace std;
int n,m;
char s[300004];
int cnt=0;
void Str()
{
    cnt=0;
    for(int i=0;i<strlen(s);i++)
    {
        if(s[i]=='.' && s[i+1]=='.')
        {
            cnt++;
        }
    }
}
int main()
{
    cin>>n>>m;
    cin>>s;

    int x;char z;
    Str();
    for(int i=1;i<=m;i++)
    {
        cin>>x>>z;
        //Str();

        if(s[x-1]<='z' && s[x-1]>='a')
        {
            if(z=='.')
            {
                if(s[x-2]=='.')cnt++;
                if(s[x]=='.') cnt++;
            }
        }
        if(s[x-1]=='.')
        {
            if(z>='a'&&z<='z')
            {
                if(s[x-2]=='.') cnt--;
                if(s[x]=='.') cnt--;
            }
        }
        cout<<cnt<<endl;
        s[x-1]=z;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章