Codeforces Round #713 (Div. 3)

Codeforces Round #713 (Div. 3)

https://codeforces.com/contest/1512

F 好题!
暑假争取天天vp

A. Spy Detected!

pair排序

#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;
pii a[100];

void solve () {
    
    int n, x = -1, y = -1;
    cin >> n;
    for (int i = 0; i < n; i ++) 
        cin >> a[i].first, a[i].second = i;
    sort (a, a + n);
    if (a[0].first == a[1].first)   cout << a[n-1].second + 1 << endl;
    else    cout << a[0].second + 1 << endl;
    

}

int main () {
    int t;
    cin >> t;
    while (t --)
        solve ();
}

B. Almost Rectangle

分两种情况:

#include <bits/stdc++.h>

using namespace std;
const int N = 405;
char a[N][N];

void solve () {
    int n;
    cin >> n;
    int r1 = -1, c1 = -1, r2 = -1, c2 = -1;
    for (int i = 0; i < n; i ++)
        for (int j = 0; j < n; j ++) {
            cin >> a[i][j];
            if (a[i][j] == '*') {
                if (r1 == -1)   r1 = i, c1 = j;
                else if (r2 == -1)  r2 = i, c2 = j;
            }
        }
            
    // cout << r1 << ' ' << c1 << endl;
    // cout << r2 << ' ' << c2 << endl;
    if (c1 == c2) {
        if (c1-1 >= 0)  a[r1][c1-1] = '*', a[r2][c2-1] = '*';
        else    a[r1][c1+1] = '*', a[r2][c2+1] = '*';
    }
    else if (r2 == r1) {
        if (r1-1 >= 0)  a[r1-1][c1] = '*', a[r2-1][c2] = '*';
        else    a[r1+1][c1] = '*', a[r2+1][c2] = '*';
    }
    else
        a[r1][c1] = '*', a[r1][c2] = '*', a[r2][c2] = '*', a[r2][c1] = '*';

    for (int i = 0; i < n; i ++) {
        for (int j = 0; j < n; j ++)
            cout << a[i][j];
        cout << endl;
    }
   
}

int main () {
    int t;
    cin >> t;
    while (t --)
        solve ();
}

C. A-B Palindrome

根据回文构造的规则,先把可确定的确定下来
然后再从a,b中剩下多的往里面填
注意在途中判断是否回文

#include <bits/stdc++.h>

using namespace std;

void solve () {
    int a, b;
    cin >> a >> b;
    string s;
    cin >> s;
    int n = a + b;

    for (int i = 0; i < n; i ++) {
        if (s[i] == '0')    a --;
        else if (s[i] == '1')    b --;
    }
    
    for (int i = 0; i <= n-i-1; i ++) {
        if (s[i] == '?' && s[n-i-1] == '?') continue;
        if (s[i] == '?') {
            if (s[n-i-1] == '0')    s[i] = '0', a --;
            else    s[i] = '1', b --;
        }
        else if (s[n-i-1] == '?') {
            if (s[i] == '0')    s[n-i-1] = '0', a --;
            if (s[i] == '1')    s[n-i-1] = '1', b --;
        }
        
    }

    string t = s;
    reverse (t.begin (), t.end ());
    if (t != s)  {
        cout << "-1\n";
        return ;
    }

    if (a == 0 && b == 0) {
        cout << s << endl;
        return ;
    } 

    for (int i = 0; i <= n-i-1; i ++) {
        if (s[i] == '?') {
            if (i == n-i-1) {
                if (a > 0)  a--, s[i] = '0';
                else if (b > 0) b --, s[i] = '1';  
            }
            else {
                if (a > 1)  a -= 2, s[i] = s[n-i-1] = '0';
                else if (b > 1) b -= 2, s[i] = s[n-i-1] = '1';  
            }
        }   
    } 
    t = s;
    reverse (t.begin (), t.end ());
    if (t != s)  {
        cout << "-1\n";
        return ;
    }

    if (a == 0 && b == 0)   cout << s << endl;
    else    cout << "-1\n";
    
}

int main () {
    int t;
    cin >> t;
    while (t --)
        solve ();
}
//a个0,b个1
//t[i]=t[n−i+1]

D. Corrupted Array

vp的时候漏了一种情况

我这里把a[]直接当成b[]输入
先排序,然后前n-1项任选n-2个数之和等于a[n]

要分两种情况考虑

  1. sum=a[n-1],x在前n-2项中
  2. sum=a[n-2],x=a[n-1] (别忘了!!)
#include <bits/stdc++.h>
#define int long long

using namespace std;
const int N = 2e5 + 5;
int a[N];

void solve () {
    int n;
    cin >> n;
    n += 2;
    int sum = 0;
    for (int i = 0; i < n; i ++)    cin >> a[i], sum += a[i];
    sort (a, a + n);

    //sum=a[n-1],x在前n-2项中
    sum -= a[n-1];
    int id = -1;
    for (int i = 0; i < n - 1; i ++) {
        int tmp = sum;
        tmp -= a[i];
        if (tmp == a[n-1]) {
            id = i;
            break;
        }
    }

    //if (id == -1)    cout << -1 << endl;
    if (id != -1) {
        for (int i = 0; i < n - 1; i ++)
            if (i != id)    cout << a[i] << ' ';
        cout << endl;
        return ;
    }

    //就是漏了这第二种情况
    //sum=a[n-2],x=a[n-1]
    sum -= a[n-2];
    if (sum != a[n-2]) cout << "-1\n";
    else {
        for (int i = 0; i < n - 2; i ++)
            cout << a[i] << ' ';
        cout << endl;
    }

}

signed main () {
    int t;
    cin >> t;
    while (t --)
        solve ();
}
//我这里把a[]直接当成b[]输入
//先排序,然后前n-1项任选n-2个数之和等于a[n]

//要分两种情况考虑
//1. sum=a[n-1],x在前n-2项中
//2. sum=a[n-2],x=a[n-1]

E. Permutation by Sum

贪心的那一步没想到
(可以根据连续的性质来进行贪心分配)

#include <bits/stdc++.h>

using namespace std;
const int N = 505;
bool vis[N];
int n, l, r, s, len;
int ans[N];

void solve () {
    memset (vis, false, sizeof vis);

    cin >> n >> l >> r >> s;
    len = r - l + 1;

    int minn = (1+len)*len/2, maxn = (2*n-len+1)*len/2;
    //cout << minn << ' ' << maxn << endl;
    if (s < minn || s > maxn) {
        cout << "-1\n";
        return ;
    }
    
    //1-n中选len个数,和为s
    //贪心找即可
    //将s与minn做差,得dx,从后往前均摊dx个
    int cnt = 0; //统计minn与s平均分配了多少次
    while (minn + (cnt + 1) * len <= s && len + (cnt + 1) <= n)
        cnt ++; //最多能整体偏移多少
    int dx = s - (minn + cnt * len); //记录不能被均分的差
    //cout << "dx: " << dx << endl;

    for (int i = l; i <= r; i ++) {
        int j = (i - l + 1) + cnt;
        if (i > r - dx)     j ++; //后dx项再++
        if (!vis[j]) {
            ans[i] = j;
            vis[j] = true;
        }
    }

    int k = 1;
    for (int i = 1; i <= n; i ++) {
        if (vis[i]) continue;
        while (k >= l && k <= r)    k ++;
        ans[k ++] = i;
    }

    // if (dx > len) {
    //     cout << "-1\n";
    //     return ;
    // }

    // //更新[l,r]
    // //1 2 ... 
    // for (int i = l, j = 1; i < l + len - dx; i ++, j ++) {
    //     pos[j] = 1;
    //     ans[i] = j;
    // }

    // //...(偏移后的后半段)
    // for (int i = r, j = len + 1; i >= l + len - dx; i --, j --) {
    //     pos[j] = 1;
    //     ans[i] = j;
    // }

    // int k = 0;
    // for (int i = 1; i <= n && k < l ; i ++) {
    //     if (pos[i] == 1)    continue;
    //     pos[i] = 1;
    //     ans[++ k] = i;
    // }

    // k = r;
    // for (int i = 1; i <= n && k <= n ; i ++) {
    //     if (pos[i] == 1)    continue;
    //     pos[i] = 1;
    //     ans[++ k] = i;
    // }

    for (int i = 1; i <= n; i ++)   cout << ans[i] << ' ';
    cout << endl;
    
}

int main () {
    int t;
    cin >> t;
    while (t --)
        solve ();
}

F. Education

两种操作:

  1. 拿当日工资
  2. 不拿工资,花b[i]提升阶层(改变第二天的工资)
    dp,不会
    点击前往学习
    小心爆int!!!
#include <bits/stdc++.h>
#define int long long

using namespace std;
const int N = 2e5 + 5;
int f[N][2], a[N], b[N], res[N];

void solve () {
    int n, c;
    cin >> n >> c;
    for (int i = 1; i <= n; i ++)    cin >> a[i];
    for (int i = 1; i < n; i ++)    cin >> b[i];

    for (int i = 1; i <= n; i ++) {
        f[i][0] = f[i-1][1] + (int)ceil(1.0*(c-res[i])/a[i]);
        f[i][1] = f[i-1][1] + (int)ceil(1.0*(b[i]-res[i])/a[i]) + 1;
        res[i+1] = res[i] + a[i]*(int)ceil(1.0*(b[i]-res[i])/a[i])-b[i];
    }
    int ans  = 0x3f3f3f3f;
    for (int i = 1; i <= n; i ++)   ans = min (ans, f[i][0]);
    cout << ans << endl;
}

signed main () {
    int t;  cin >> t;
    while (t --) {
        solve ();
    }
}
//注意这里的除都是上取整
//f[i][0] = f[i-1][1] + (c-res[i])/a[i]
//f[i][1] = f[i-1][1] + (b[i]-res[i])/a[i] + 1
//res[i+1] = res[i] + a[i]*((b[i]-res[i])/a[i])-b[i]

G. Short Task

n的所有因子之和等于c,求最小的n
打表

#include <bits/stdc++.h>

using namespace std;
const int N = 1e7;
int ans[N+1], a[N+1];

//暴力打表
void pre () {
    for (int i = 1; i <= N; i ++) { //第一个因子
        for (int j = i; j <= N; j += i) 
            a[j] += i; //第二个因子
        if (a[i] <= N && ans[a[i]] == 0)
            ans[a[i]] = i;
    }
    for (int i = 1; i <= N; i ++)
        if (ans[i] == 0)    ans[i] = -1;
}

void solve () {
    int n;
    cin >> n;
    cout << ans[n] << endl;
}

int main () {
    pre();
    int t;
    cin >> t;
    while (t --)    solve ();
}

//先-1,得质数直接输出
//否则继续分解到质数因子
posted @ 2022-07-05 23:41  Sakana~  阅读(28)  评论(0编辑  收藏  举报