2021年1月16日sdut vj个人赛

A - Abandoned Animal

题目链接

题目思路就是按输入物品的顺序买到物品,如果不能就输出impossible,如果有唯一的顺序就输出unique,有多个情况就输出ambiguous。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;

map<string , int> mp;
vector<int> a[N];
int b[N];
int n, k, m, ii, ans, buy1[N], buy2[N];
string s;

int main()
{
    
    
    memset(buy1, -1, sizeof buy1);
    memset(buy2, -1, sizeof buy2);
    int f = 0;
    cin >> n >> k;
    for(int i = 0; i < k; i ++)
    {
    
    
        cin >> ii >> s;
        if(mp.count(s)) a[ii].push_back(mp[s]);
        else
        {
    
    
            mp[s] = f;
            a[ii].push_back(f ++);
        }
    }
    cin >> m;
    for(int i = 0; i < m; i ++)
    {
    
    
        cin >> s;
        b[i] = mp[s];
    }
    ans = 0;
    int idx = 0;
    for(int i = 0; i < n && idx < m; i ++)
    {
    
    
        int len = a[i].size();
        for(int j = 0; j < len; j ++)
        {
    
    
            if(a[i][j] == b[idx])
            {
    
    
                buy1[idx] = i;
                idx ++;
                i --;
                break;
            }
        }
    }
    if(buy1[m - 1] != -1) ans ++;
    idx = m - 1;
    for(int i = n - 1; i >= 0 && idx >= 0; i --)
    {
    
    
        int len = a[i].size();
        for(int j = len - 1; j >= 0; j --) 
        {
    
    
            if(a[i][j] == b[idx])
            {
    
    
                buy2[idx] = i;
                idx --;
                i ++;
                break;
            }
        }
    }
    if(buy2[0] != -1) ans ++;
    if(ans == 0) cout << "impossible" <<endl;
    else if(ans == 1) cout << "unique" << endl;
    else
    {
    
    
        int flag = 1;
        for(int i = 0; i < m; i ++)
        {
    
    
            if(buy1[i] != buy2[i])
            {
    
    
                flag = 0;
                break;
            }
        }
        if(flag) cout << "unique" << endl;
        else cout << "ambiguous" << endl;
    }
}

D - Disastrous Doubling

题目链接

题意:

一个细胞从1个开始以2倍增长,第一天变成2,第二天变成4,第三天变成8。每天研究员会拿走若干个,如果中途细胞不够用就输出error,不然就输出最后剩多少个细胞。

题解:

此题数据量较大,要对1e9+ 7取模。通过找规律,可发现一旦细胞数量超过研究员拿走细胞最大值的2倍。那么之后的细胞一定够用,所以就能用num = (num * 2 % mod - a[i] % mod + mod) % mod这样的式子进行计算,但是要有error判断细胞数量为负值的情况。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5 + 10;
const int mod = 1e9 + 7;
ll a[N];
int flag = 0;
ll num = 1;

int main() {
    
    
    int n;
    cin >> n;
    ll maxx = 0;
    for (int i = 0; i < n; i++) {
    
    
        cin >> a[i];
        maxx = max(maxx, a[i]);
    }
    maxx *= 2;
    for (int i = 0; i < n; i++) {
    
    
        if (flag) {
    
    
            num = (num * 2 % mod - a[i] % mod + mod) % mod;
        } else {
    
    
            num *= 2;
            if (num >= maxx) flag = 1;
            num -= a[i];
            if (num < 0) {
    
    
                cout << "error" << endl;
                return 0;
            }
        }
    }
    cout << num % mod << endl;
    return 0;
}

E - Envious Exponents

题目链接
题目大意就是找出的最小的比n大的数x,并且二进制表示方法里1个数等于k。
分三种情况:
(1)如果ans > k,从低位遍历x的二进制表示,如果为1,就变成0,直到ans = k。再转到第二种情况。
(2)如果ans = k,把第一个非前置0变成1,再从这个位置往低位遍历,如果为1就变成0。
(3)如果ans < k,就从低位往高位遍历,如果是0就变成1,直到ans = k。

#include <bits/stdc++.h>

using namespace std;
int q[100];
int main() {
    
    
    long long N, M;
    int k;
    int top = 0, ans = 0;
    cin >> N >> k;
    M = N;
    while (M != 0) {
    
    
        q[++top] = M % 2;
        if (M % 2 == 1) ans++;
        M /= 2;
    }
    if (ans > k)
    {
    
    
        for (int i = 1; i <= top; i++) {
    
    
            if (q[i] == 1) {
    
    
                q[i] = 0;
                ans--;
            }
            if (ans == k) break;
        }
    }
    int cnt = 0;
    int flag = 0;
    if (ans == k)
    {
    
    
        for (int i = 1; i <= 100; i++) {
    
    
            if (q[i] == 1) {
    
    
                flag = 1;
            }
            if (q[i] == 0 && flag == 1) {
    
    
                cnt = i;
                q[i] = 1;
                ans++;
                break;
            }
        }
        for (int i = cnt - 1; i >= 1; i--) {
    
    
            if (q[i] == 1) {
    
    
                q[i] = 0;
                ans--;
            }
        }
        for (int i = 1; i <= cnt; i++) {
    
    
            if (ans == k)
                break;
            else if (ans < k) {
    
    
                q[i] = 1;
                ans++;
            }
        }
    }
    if (ans < k)
    {
    
    
        for (int i = 1;; i++) {
    
    
            if (q[i] == 0) {
    
    
                q[i] = 1;
                ans++;
            }
            if (ans == k) break;
        }
    }
    long long sum = 0;
    long long x = 1;
    for (int i = 1; i <= 100; i++) {
    
    
        if (q[i] == 1) {
    
    
            sum = sum + x;
        }
        x = x * 2;
    }
    cout << sum << endl;
    return 0;
}

H - Horror Film Night

题目链接

题意:

题意:两个人一起电影,每天看一部,输入第一行为n,a1,a2……an;代表第一个人喜欢看的电影总数n,其后是喜欢看的电影的编号。输入第二行为m,b1,b2……bn;代表第二个人喜欢看的电影总数m,其后是喜欢看的电影的编号。两个人只能看两个人都喜欢的电影或者其中一人喜欢另一个人不喜欢的电影,且不能连续看一个人单独喜欢的电影,求出能看电影的最大数目。

题解:

book[i]代表第i天喜欢看电影的情况,book[i]=0代表两个人都不喜欢,book[i]=1代表第一个人喜欢,book[i]=2代表第二个人喜欢,book[i]=3代表两个人都喜欢。用标记变变量标记上一次是什么情况。然后判断这一次那种情况可行。如果可以,将标记变量更新,并且将计数变量ans++。

#include <bits/stdc++.h>
using namespace std;
int a[1000010];
int b[1000010];
int book[1000010];
int main() {
    
    
    int n, m;
    cin >> n;
    for (int i = 0; i < n; i++) {
    
    
        cin >> a[i];
        book[a[i]] += 1;
    }
    cin >> m;
    for (int i = 0; i < m; i++) {
    
    
        cin >> b[i];
        book[b[i]] += 2;
    }
    sort(a, a + n);
    sort(b, b + m);
    int ans = 0;
    int cur = 0;
    int maxx = max(a[n - 1], b[m - 1]);
    for (int i = 0; i <= maxx; i++) {
    
    
        if (book[i] == 0) {
    
    
            continue;
        } else if (book[i] == 1) {
    
    
            if (cur == 0 || cur == 2 || cur == 3) {
    
    
                ans++;
                cur = 1;
            } else if (cur == 1) {
    
    
                continue;
            }
        } else if (book[i] == 2) {
    
    
            if (cur == 0 || cur == 1 || cur == 3) {
    
    
                ans++;
                cur = 2;
            } else if (cur == 2) {
    
    
                continue;
            }
        } else if (book[i] == 3) {
    
    
            ans++;
            cur = 3;
        }
    }
    cout << ans << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_47783181/article/details/112754936