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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章