Codeforces Round #612 (Div. 2)

题库链接

https://codeforces.com/contest/1287

A. Angry Students

n个人,生气的人A会丢雪球打不生气的人,然后不生气的生气了
模拟

#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 200100;
const int M = 1e9+7;
int n,m,k,t;
 
char s[110];
 
bool solve()
{   
    bool flag = 0;
    for(int i = 0; i < n-1; i++) 
    {
        if(s[i] == 'A' && s[i+1] == 'P')
        {
            flag = 1;
            s[i+1] = 'A';
            i++;
        }
    }
    //cout<<s<<endl;
    return flag;
}
 
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("data.in", "r", stdin);
#endif
    cin(t);
    while(t--)
    {
        cin(n);
        cin>>s;
        int ans = 0;
        while(solve()) ans++;
        cout<<ans<<endl;
    }
    return 0;
}

B. Hyperset

有一副牌,k个属性,选出三张,对于每个属性,要么全部相同,要么全部不同
暴力匹配,只需要枚举前两张牌,用hash记录一下

#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 2000;
const int M = 1e9+7;
int n,m,k,t;
 
char s[maxn][32];
map<string,int> mp;
bool vis[3];
 
bool judge(int i,int j)
{
    char str[32];
    for(int l = 0; l < m; l++)
    {   
        vis[1] = vis[2] = vis[0] = 0;
        if(s[i][l] == s[j][l]) str[l] = s[i][l];
        else 
        {
            if(s[i][l] == 'S' || s[j][l] == 'S') vis[0] = 1;
            if(s[i][l] == 'E' || s[j][l] == 'E') vis[1] = 1;
            if(s[i][l] == 'T' || s[j][l] == 'T') vis[2] = 1;
            if(!vis[0]) str[l] = 'S';
            else if(!vis[1]) str[l] = 'E';
            else if(!vis[2]) str[l] = 'T';
        }
    }
    str[m] = '\0';
    //cout<<s[i]<<' '<<s[j]<<' '<<str<<' '<<mp[str]<<endl;
    if(mp[str] > j) return true;
    return false;
}
 
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("data.in", "r", stdin);
#endif
    cin(n);cin(m);
    for(int i = 0; i < n; i++) 
    {
        scanf("%s",s[i]);
        mp[s[i]] = i;
    }
    int ans = 0;
    for(int i = 0; i < n; i++) 
    {
        for(int j = i+1; j < n; j++) 
        {   
            if(judge(i,j)) ans++;
        }
    }
    cout<<ans<<endl;
    return 0;
}

C. Garland

有一个序列,1-n,0代表空,如何填充这个序列,使得相邻灯泡奇偶对数最小
dp,dp[i][j][k]表示前i个数,用了j个偶数,k表示第i个数是奇数还是偶数

#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 110;
const int M = 1e9+7;
int n,m,k,t;

int a[maxn];
int dp[maxn][maxn][2];

int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("data.in", "r", stdin);
#endif
    cin(n);
    for(int i = 1; i <= n; i++) 
    {
        cin(a[i]);
    }
    mem(dp,inf);
    dp[0][0][0] = dp[0][0][1] = 0;
    for(int i = 1; i <= n; i++) 
    {
        for(int j = 0; j <= i; j++) 
        {
            if(a[i]%2 == 0)
            {
                dp[i][j][0] = min(dp[i-1][j-1][0],dp[i-1][j-1][1]+1);
            }
            if(a[i]%2 || a[i]==0)
            {
                dp[i][j][1] = min(dp[i-1][j][1],dp[i-1][j][0]+1);
            }
        }
    }
    cout<<min(dp[n][n/2][0],dp[n][n/2][1])<<endl;
    return 0;
}

D. Numbers on Tree

n个节点,每一个节点有一个值,并且有一个c,表示他的子孙里面有c个值比他的值小
题目给出树的结构和c的值,求出满足题意的节点的值

#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 2100;
const int M = 1e9+7;
int n,m,k,t;
 
int c[maxn];
int sz[maxn];       //记录i有多少个节点
int ans[maxn];
 
vector<int> a[maxn];        //图
vector<int> rk;
 
void dfs(int u,int fa)
{
    sz[u] = 1;
    for(auto v : a[u])
    {
        if(v!=fa) dfs(v,u);
        sz[u] += sz[v];
    }
    if(c[u] >= sz[u])
    {
        puts("NO");exit(0);
    }
    rk.insert(rk.begin()+c[u],u);
}
 
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("data.in", "r", stdin);
#endif
    cin(n);
    int root = 0;
    for(int i = 1,x; i <= n; i++) 
    {
        scanf("%d%d",&x,&c[i]);
        if(x == 0) root = i;
        else a[x].push_back(i);
    }
    dfs(root,0);
    for(int i = 0; i < n; i++) 
    {
        ans[rk[i]] = i+1;
    }
    puts("YES");
    for(int i = 1; i <= n; i++) 
    {
        cout<<ans[i]<<' ';
    }
    return 0;
}

E1. Madhouse (Easy version)

给定一个字符串长度n,你有三次询问机会,? l r表示询问区间[l,r],返回区间[l,r]的全部子串,但是顺序会打乱,求出这个字符串
其实我们只需要询问两次就好了,询问? 1 n? 2 n,并且用第一次的结果减去第二次的结果,你就会发现你只剩下n个不同长度的字符串了

#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 110;
const int M = 1e9+7;
int n,m,k,t;

multiset <string> st;
string ans = " ";
string f[maxn];

int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("data.in", "r", stdin);
#endif
    cin(n);
    cout<<"? 1 "<<n<<endl;
    fflush(stdout);
    for(int i = 1; i <= n; i++) 
    {
        for(int j = i; j <= n; j++) //长度为i的有n-i+1个
        {
            string tmp;
            cin>>tmp;
            sort(tmp.begin(),tmp.end());
            st.insert(tmp);     //插入
        }
    }
    if(n == 1)
    {
        cout<<"! "<<*st.begin()<<endl;
        return 0;
    }

    cout<<"? 2 "<<n<<endl;
    fflush(stdout);
    for(int i = 2; i <= n; i++) 
    {
        for(int j = i; j <= n; j++) 
        {
            string tmp;
            cin>>tmp;
            sort(tmp.begin(),tmp.end());
            st.erase(st.find(tmp));      //只删除一个,如果是st.erase(tmp);会删除多个
        }
    }
    //st里面只剩下n个数,而且是n个长度不同的数
    
    for(auto tmp : st)
    {
        f[tmp.size()] = tmp;
    }
    ans += f[1];
    int mark[30];
    for(int j = 2; j <= n; j++)
    {
        mem(mark,0);
        for(auto i : f[j])
        {
            mark[i-'a']++;
        }
        for(auto i : ans)
        {
            mark[i-'a']--;
        }
        for(int i = 0; i < 30; i++)
        {
            if(mark[i]) ans += char(i+'a');
        }
    }
    cout<<"!"<<ans<<endl;
    return 0;
}
posted @ 2020-01-06 10:10  hezongdnf  阅读(287)  评论(0)    收藏  举报