2021 年第十三届四川省 ACM-ICPC 大学生程序设计竞赛(A/B/D/H/E/K/M/L)

https://codeforces.com/gym/103117

A.

水题

int main() {
    IOS;
    int t;
    cin >> t;
    while(t--){
        int k;
        cin >> k;
        if(k > 12)
            cout << 0 << endl;
        else {
            int ans = 0;
            for (int i = 1; i <= 6; ++i){
                for (int j = i; j <= 6; ++j){
                    if(i + j > k)
                        break;
                    else if(i + j == k)
                        ++ans;
                }
            }
            cout << ans << endl;
        }
    }
    return 0;
}

B.

这不上次做的澳门热身赛题嘛
又错了好多次…人麻了
重做第三次…麻了

在每一步都需要算式和图去验证
······················奇数次:
··········奇数位:
·····················偶数次:
奇数个:
·····················奇数次:
··········偶数位: ·
····················偶数次:

https://blog.csdn.net/m0_50007959/article/details/124490018?spm=1001.2014.3001.5501

int val[maxn];
map<int, int> mp;
int sat[maxn];

int main() {
    IOS;
    int t;
    cin >> t;
    while(t--){
        re(sat);
        re(val);
        mp.clear();
        int n, k, m;
        cin >> n >> k >> m;
        for (int i = 1; i <= n; ++i){
            cin >> val[i];
            ++mp[val[i]];//记下是奇数个
            sat[i] = mp[val[i]];//赋给这一位
        }

        int na = m / n, nb = m % n;
        for(int i = 1; i <= n; ++i){
            int te = 0;
            if(mp[val[i]] % 2 == 0){
                if(sat[i] % 2)
                    te = 0;
                else
                    te = na + (nb >= i);
            }
            else {
                te = na / 2;
                if(sat[i] % 2 == 1){
                    if(na % 2 == 1)
                        te += (nb >= i);
                }
                else {
                    if(na % 2 == 1){
                        ++te;
                    }
                    else
                        te += (nb >= i);
                }
            }
            if (i == 1)
                cout << te;
            else
                cout << " " << te;
        }
        if(t >= 1)
            cout << endl;
    }
    return 0;
}

D.

题没读懂,看了眼题解才明白题是什么意思,居然连石头剪刀布都没看出来orz,这题也是越来越熟悉了
想起来了,确实做过,和临时队友A了三还是四来着
老是错,原来问题出在减后再取min再减

int main() {
    IOS;
    ll t;
    cin >> t;
    while(t--){
        ll a[3], b[3];
        cin >> a[0] >> a[1] >> a[2];
        cin >> b[0] >> b[1] >> b[2];

        ll ans = 0;
        if(a[0] != 0){
            if(b[1] != 0) {
                ans += min(a[0], b[1]);
                a[0] -= min(a[0], b[1]);
                b[1] -= min(a[0], b[1]);
            }
        }
        //cout << ans << " ";
        if(a[1] != 0){
            if(b[2] != 0) {
                ans += min(a[1], b[2]);
                a[1] -= min(a[1], b[2]);
                b[2] -= min(a[1], b[2]);
            }
        }
        //cout << ans << " ";
        if(a[2] != 0){
            if(b[0] != 0) {
                ans += min(a[2], b[0]);
                a[2] -= min(a[2], b[0]);
                b[0] -= min(a[2], b[0]);
            }
        }
        //cout << ans << " ";
        //cout << a[0] << " " << a[1] << " " << a[2] << ' ';
        //再耗平局
        if(a[0] != 0){
            if(b[0] != 0) {
                a[0] -= min(a[0], b[0]);
                b[0] -= min(a[0], b[0]);
            }
        }
        if(a[1] != 0){
            if(b[1] != 0) {
                a[1] -= min(a[1], b[1]);
                b[1] -= min(a[1], b[1]);
            }
        }
        if(a[2] != 0){
            if(b[2] != 0) {
                a[2] -= min(a[2], b[2]);
                b[2] -= min(a[2], b[2]);
            }
        }
        ans = ans - b[0] - b[1] - b[2];
        cout << ans << endl;
    }
    return 0;
}

K.

在之前澳门热身赛也做过,水题

M.

结论大致推出来了,没有往下深挖,wa了一发后陷入了迷茫觉得不会,居然很简单。只需要判最大的时间,最大时间都过不去,其它时间都在摆烂,肯定也过不去。
能过去的之前一定在摆烂,只有这一次过去了,且能过去。
不开ll见祖宗

ll sp[maxn];
ll a[maxn];

int main() {
	IOS;
	// freopen("P1908_6.in","r",stdin);//读入数据
	// freopen("P1908.out","w",stdout); //输出数据
    //只算大于移进去的
    ll n, k, x, p;
    cin >> n >> k >> x >> p;//判时差
    for (int i = 1; i <= n; ++i){
        cin >> sp[i];
    }
    for (int i = 1; i <= k; ++i){
        cin >> a[i];
    }
    for (int i = 1; i <= k; ++i){
        int t;
        cin >> t;
        p = max(p, t - a[i]);
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i){
        if(sp[i] * p >= x)
            ++ans;
    }
    cout << ans;
    return 0;
}

L.

果然,这个数据范围和题意就不该是判两点,而是点到某个值的距离
完蛋,老是卡在4%,明明经过大改也在4%,就离谱
看了眼题解,啊5e5搜不完,应该搜100的标记,再去试试
逛了一圈答案,基本全用链式前向星
md谁能懂啊,dist[1e5][110]会超限卡80%,dist[110][1e5]就过了

int n, m, q;
int val[maxn];
vector<int> v[maxn];
int dist[110][maxn];

void dij(int x){
    //哈哈毁灭吧,淦
    //我是真的不想写了
    queue<int> qq;
    for (int i = 1; i <= n; ++i){
        if(val[i] <= x){
            qq.push(i);
            dist[x][i] = 0;
        }
    }
     while(!qq.empty()){
        int u = qq.front();
        qq.pop();
        if(vis[u]) continue;//不加标记也可以,习惯了加标记
        vis[u] = true;
        for(auto w : v[u]) {
            if(!vis[w] && dist[x][w] > dist[x][u] + 1) {
                dist[x][w] = dist[x][u] + 1;
                qq.push(w);
            }
        }
    }
}

int main() {//感觉signed很好用,起码一样的硬卡过去了4%的数据
    scanf("%d%d%d",&n,&m,&q);//cin关了同步也能过
    for (int i = 1; i <= n; ++i){
        scanf("%d", &val[i]);
    }
    for (int i = 1; i <= m; ++i){
        int a, b;
        scanf("%d%d",&a,&b);
        v[a].push_back(b);
        v[b].push_back(a);
    }
    remax(dist);
    for (int i = 1; i <= 100; ++i){
        dij(i);
    }
    
        for (int i = 1; i <= q; ++i)
        {
            int a, b;
            scanf("%d %d",&a,&b);
            int ans = dist[b][a];
                if (ans == 0x3f3f3f3f)
                    ans = -1;
                printf("%d\n", ans);
        }
        return 0;
}

H.

水题,一年前的我都会写,纯判字符串

E.

看题解吧:
点我
点我

vector<int> v[maxn];
int cnt, now;
int n, m;
void dfs(int st){
    if(st == n + 1)
        return;
    for (int i = 0; i < v[st].size(); ++i){
        while(v[st][i] >= now){//如果now初始为1,这里改v - 1==
            if(v[st][i] == now){//v - 1 ==
                ++now;
                dfs(now - 1);//dfs(now)下一个数
            }
            else{
                ++cnt;
                ++now;
                dfs(now - 1);
            }
        }
    }
}
//感觉哈,在我能力之外,大概懂,仔细不会
signed main() {
	IOS;
    int t;
    cin >> t;
    while(t--){
        cnt = 0, now = 2;
        cin >> n >> m;
        for (int i = 1; i <= m; ++i){
            int a, b;
            cin >> a >> b;
            v[a].push_back(b);
            v[b].push_back(a);
        }
        v[1].push_back(n + 1);
        for (int i = 1; i <= n; ++i){
            sort(v[i].begin(), v[i].end());
        }
        dfs(1);
        cout << cnt << endl;
        for(int i=1;i<=n;i++)	v[i].clear();
    }
    return 0;
}

你可能感兴趣的:(补题日记,算法)