《寒假每日一题 2022》

1960. 闪烁

题目链接
https://www.acwing.com/problem/content/1962/

分析

  • 状态压缩:将二进制转化为十进制
  • 状态转移:在十进制状态下进行转移
    	int last = num & 1; 
    	int temp = (num >> 1) + (last << n - 1); 
    	num = num ^ temp; 
    
  • 计算答案(容易出错,算明白了再写,尤其注意T=1的情况)

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>

using namespace std;

typedef long long ll;

map<ll, bool> st;
map<ll, ll> tt;
map<ll, ll> ans;
ll n, t;

int main()
{
    scanf("%lld%lld", &n, &t);
    ll num = 0;
    for(int i = 0; i < n; i ++){
        int x;
        scanf("%d", &x);
        num = num * 2 + x;
    }
    //st[num] = true;
    //tt[num] = 0;
    //ans[0] = num;
    
    bool flag = true;
    int stop = 0;
    for(int i = 1; i <= t; i ++){
        int last = num & 1; 
        int temp = (num >> 1) + (last << n - 1); 
        num = num ^ temp; 
        //cout << num  << endl;
        if(st[num]) {
            stop = i;
            flag = false;
            break;
        }
        st[num] = true;
        tt[num] = i;
        ans[i] = num;
    }
    if(flag == false){
        ll tag = tt[num];
        ll T = stop - tag;
        ll res;
        if(T == 1) res = stop - 1;
        else res = (t - tag + 1) % T + tag - 1;
        //cout << tag << ' ' << t << ' ' << stop << endl;
        num = ans[res];
    }

    for(int i = n - 1; i >= 0; i --){
        int x = (num >> i) & 1;
        printf("%d\n", x);
    }
    return 0;
}

1945. 奶牛棒球

题目链接
https://www.acwing.com/problem/content/1947/

解析
暴力枚举x、z(z > x),二分查找是否有满足条件的y,一直x、z后y的范围很容易推。
y的范围可以用double表示,不用考虑取整问题。

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1010;

typedef long long ll;

int a[N];
int n;

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
    sort(a + 1, a + n + 1);
    
    ll ans = 0;
    for(int i = 1; i <= n; i ++){
        for(int j = i + 1; j <= n; j ++){
            int x = a[i], z = a[j];
            //cout << x << ' ' << z << endl;
            double left = (double)(2 * x + z) / 3.0, right = (double)(x + z) / 2.0;
            //cout << left << ' ' << right << endl;
            int l = i, r = j;
            while (l < r) {
                int mid = l + r >> 1;
                if ((double)a[mid] >= left) r = mid;
                else l = mid + 1;
            }
            int ll = l;
            l = i, r = j;
            while (l < r)
            {
                int mid = l + r + 1 >> 1;
                if ((double)a[mid] <= right) l = mid;
                else r = mid - 1;
            }
            int rr = l;
            //cout << ll << ' ' << rr << endl;
            ans += max(0, rr - ll + 1);
            //puts("");
        }
    }
    printf("%lld\n", ans);
    
    return 0;
}

1934. 贝茜放慢脚步

题目链接
https://www.acwing.com/problem/content/1936/

解析
问题的本质是做一个两路归并,写代码的时候要明确需要维护的值,对于每一个要减慢速度的点,我们应当记录在减慢速度前已消耗的时间T和已走过的路程S,同时注意中有round(double x)函数方便进行四舍五入。

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>

using namespace std;

const int N = 1e4 + 10;

double tt[N], dd[N];
double T, S;
char op;
int tidx, didx, n;

int main()
{
    scanf("%d\n", &n);
    while(n --){
        double x;
        scanf("%c %lf\n", &op, &x);
        //cout << op << ' ' << x << endl;
        if(op == 'T') tt[tidx ++] = x;
        else dd[didx ++] = x;
    }
    sort(tt, tt + tidx);
    sort(dd, dd + didx);
    
    int k = 1, i = 0, j = 0;
    while(i < tidx && j < didx){
        double td = (dd[j] - S) * k;
        if(td < tt[i] - T){
            T += td;
            S = dd[j];
            k ++, j ++;
        }
        else{
            S += (tt[i] - T) / (double)k;
            T = tt[i];
            k ++, i ++;
        }
    }
    while(i < tidx){
        S += (tt[i] - T) / (double)k;
        T = tt[i];
        k ++, i ++;
    }
    while(j < didx){
        T += (dd[j] - S) * k;
        S = dd[j];
        k ++, j ++;
    }
    T += (1000 - S) * k;
    printf("%.0lf\n", round(T));
    return 0;
}

1922. 懒惰的牛

题目链接
https://www.acwing.com/activity/content/problem/content/6539/

解析

  • 注意xi的范围不利于做前缀和处理,所以整体+1
  • 有点离散话的意思,不要把数据范围看花眼了
  • mmax好像不可以用N直接替代,感觉有点奇怪。。。

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long ll;

const int N = 1e7 + 10;

int a[N];
ll s[N];
int n, k;

int main()
{
    scanf("%d%d", &n, &k);
    int mmax = 0;
    for(int i = 1; i <= n; i ++) {
        int x, y;
        scanf("%d%d", &y, &x);
        a[x + 1] = y;
        mmax = max(mmax, x + 1);
    }
    for(int i = 1; i <= mmax; i ++) s[i] = s[i - 1] + a[i];
    ll ans = 0;
    for(int i = 1; i <= mmax; i ++){
        int l = max(1, i - k), r = min(mmax, i + k);
        ans = max(ans, s[r] - s[l - 1]);
    }
    printf("%lld\n", ans);
    
    return 0;
}

1913. 公平摄影

题目链接
https://www.acwing.com/problem/content/1915/

解析
题目表述不清晰,关于题目的分析:
https://www.acwing.com/solution/content/85524/

具体做法:
比较巧妙的一点是将两种牛的tag设置为1、-1,原题转化为哪些段的和为0,有两种情况:

  • s[i] = 0, 从第一头牛到第i头牛和为0

  • s[i] = s[j] != 0, 从 i + 1 到 j 和为 0

这两种情况可以合并,可以通过设s[0] = 0实现

由于数据范围问题,通过pair和map来存储数据;

只包含一种牛的情况用双指针来做,代码写的不够熟练,主要是由于对于循环终止状态不够清晰。

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>

using namespace std;

const int N = 1e5 + 10;

typedef long long ll;
typedef pair<ll, ll> PII;

int n;
PII a[N];
ll s[N];
map<ll, bool> st;
map<ll, ll> pos;

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++)
    {
        ll x;
        char op;
        scanf("%lld %c\n", &x, &op);
        if(op == 'G') a[i] = {x, 1};
        else a[i] = {x, -1};
    }
    sort(a + 1, a + n + 1);
    for(int i = 1; i <= n; i ++)
        s[i] = s[i - 1] + a[i].second;
        //printf("%d ", s[i]);  //s的范围是1-n
    
    ll ans = 0;
    for(int i = 1; i <= n; i ++){
        if(s[i] == 0) ans = max(ans, a[i].first - a[1].first);
        else{
            if(!st[s[i]]) {
                st[s[i]] = true;
                pos[s[i]] = i;
            }
            else{
                ans = max(ans, a[i].first - a[pos[s[i]] + 1].first);
            }
        }
    }
    
    ll res = 0, i = 1;
    while(i <= n && a[i].second != -1) i ++;
    while(i <= n){
        int j = i;
        while(j <= n && a[j].second != 1) j ++;
        res = max(res, a[j - 1].first - a[i].first);
        //printf("%lld ", res);
        while(j <= n && a[j].second != -1) j ++;
        i = j;
    }
    ans = max(ans, res);
    
    res = 0, i = 1;
    while(i <= n && a[i].second != 1) i ++;
    while(i <= n){
        int j = i;
        while(j <= n && a[j].second != -1) j ++;
        res = max(res, a[j - 1].first - a[i].first);
        //printf("%lld ", res);
        while(j <= n && a[j].second != 1) j ++;
        i = j;
    }
    ans = max(ans, res);
    //puts("");
    //printf("%lld %lld\n", ans, res);
    printf("%lld\n", ans);
    
    return 0;
}

1904. 奶牛慢跑

题目链接
https://www.acwing.com/activity/content/problem/content/6541/

解析
用栈挺好的,但是懒得搞了,写了个离散化for了一遍也可以

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>

using namespace std;

const int N = 1e5 + 10;

typedef pair<int, int> PII;

int n;
PII a[N];

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++){
        int x, v;
        scanf("%d%d", &x, &v);
        a[i] = {x, v};
    }
    int cnt = 0, vv = a[n].second;
    for(int i = n; i >= 1; i --){
        if(a[i].second <= vv) cnt ++;
        vv = min(vv, a[i].second);
    }
    printf("%d\n", cnt);

    return 0;
}

1843. 圆形牛棚

题目链接
https://www.acwing.com/problem/content/1845/

解析
暴力

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1010;

int a[N];
int ans = 0x3f3f3f3f;
int n;

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);

    for(int i = 1; i <= n; i ++){
        int res = 0;
        for(int j = 1; j <= n; j ++){
            res += (j + n - i) % n * a[j]; 
        }
        ans = min(ans, res);
    }
    printf("%d\n", ans);

    return 0;
}

1826. 农田缩减

题目链接
https://www.acwing.com/problem/content/1828/

解析
简单分类讨论,没想到除了longlong忘开没有错误,就是做的时候不想做,中间刷了1h视频。。。(对不起这个世界呜呜呜)

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 5e4 + 10;

typedef long long ll;
typedef pair<ll, ll> PII;

PII a[N], b[N];
ll xmin, xmax, ymin, ymax;
ll ans;
int n;

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++){
        int x, y;
        scanf("%d%d", &x, &y);
        a[i] = {x, y};
        b[i] = {y, x};
    }
    sort(a + 1, a + n + 1);
    sort(b + 1, b + n + 1);
    
    xmin = a[1].first, xmax = a[n].first;
    ymin = b[1].first, ymax = b[n].first;
    //cout << xmin << ' ' << xmax << ' ' << ymin << ' ' << ymax << endl;
    
    //情况一:去掉y最大的一点
    ll ax = b[n].second, by = b[n].first;
    ymax = b[n - 1].first;
    if(ax == xmin) xmin = a[2].first;
    if(ax == xmax) xmax = a[n - 1].first;
    ans = (ymax - ymin) * (xmax - xmin);
    //printf("%d\n", (ymax - ymin) * (xmax - xmin));
    
    xmin = a[1].first, xmax = a[n].first;
    ymin = b[1].first, ymax = b[n].first;
    
    //情况二:去掉y最小的一点
    ax = b[1].second, by = b[1].first;
    ymin = b[2].first;
    if(ax == xmin) xmin = a[2].first;
    if(ax == xmax) xmax = a[n - 1].first;
    ans = min(ans, (ymax - ymin) * (xmax - xmin));
    //printf("%d\n", (ymax - ymin) * (xmax - xmin));
    
    xmin = a[1].first, xmax = a[n].first;
    ymin = b[1].first, ymax = b[n].first;
    
    //情况三:去掉x最小的一点
    ax = a[1].first, by = a[1].second;
    xmin = a[2].first;
    if(by == ymin) ymin = b[2].first;
    if(by == ymax) ymax = b[n - 1].first;
    ans = min(ans, (ymax - ymin) * (xmax - xmin));
    //printf("%d\n", (ymax - ymin) * (xmax - xmin));
    
    xmin = a[1].first, xmax = a[n].first;
    ymin = b[1].first, ymax = b[n].first;
    
    //情况四:去掉x最大的一点
    ax = a[n].first, by = a[n].second;
    xmax = a[n - 1].first;
    if(by == ymin) ymin = b[2].first;
    if(by == ymax) ymax = b[n - 1].first;
    ans = min(ans, (ymax - ymin) * (xmax - xmin));
    //printf("%d\n", (ymax - ymin) * (xmax - xmin));
    
    printf("%lld\n", ans);
    
    return 0;
}

1813. 方块游戏

题目链接
https://www.acwing.com/problem/content/1815/

解析
对于每个木块来说,因为要满足正面和反面两种情况,所以对于每个木块,所需要的字母个数是正反面对应字母个数的最大值,n个木块只要累加即可。
做题之前要分析分析,将目标问题化简,不要试图通过高级的方法搞暴力。

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 30;

int a[N];
int cnt1[N], cnt2[N];
char s1[N], s2[N];
int n;

int main()
{
    scanf("%d", &n);
    while(n --)
    {
        scanf("%s %s", s1, s2);
        
        memset(cnt1, 0, sizeof cnt1);
        memset(cnt2, 0, sizeof cnt2);
        int len = strlen(s1);
        for(int i = 0; i < len; i ++) cnt1[s1[i] - 'a'] ++;
        len = strlen(s2);
        for(int i = 0; i < len; i ++) cnt2[s2[i] - 'a'] ++;
        
        for(int i = 0; i < 26; i ++){
            a[i] += max(cnt1[i], cnt2[i]);
        }
    }
    for(int i = 0; i < 26; i ++) printf("%d\n", a[i]);
    return 0;
}

1801. 蹄子剪刀布

题目链接
https://www.acwing.com/problem/content/1803/

解析
大力出奇迹,喜提一发Ac。

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110;

typedef pair<int, int> PII;

int n;
int score[5];
PII a[N];

int check1(int a, int b){
    if(a == 1 && b == 2) return 1;
    if(a == 2 && b == 2) return 1;
    if(a == 3 && b == 1) return 1;
    if(a == b) return 0;
    return 2;
}

int check2(int a, int b){
    if(a == 1 && b == 3) return 1;
    if(a == 2 && b == 1) return 1;
    if(a == 3 && b == 2) return 1;
    if(a == b) return 0;
    return 2;
}

int check3(int a, int b){
    if(a == 1 && b == 2) return 1;
    if(a == 2 && b == 3) return 1;
    if(a == 3 && b == 1) return 1;
    if(a == b) return 0;
    return 2;
}

int check4(int a, int b){
    if(a == 1 && b == 3) return 1;
    if(a == 2 && b == 1) return 1;
    if(a == 3 && b == 2) return 1;
    if(a == b) return 0;
    return 2;
}

int check5(int a, int b){
    if(a == 1 && b == 3) return 1;
    if(a == 2 && b == 1) return 1;
    if(a == 3 && b == 2) return 1;
    if(a == b) return 0;
    return 2;
}

int check6(int a, int b){
    if(a == 1 && b == 2) return 1;
    if(a == 2 && b == 3) return 1;
    if(a == 3 && b == 1) return 1;
    if(a == b) return 0;
    return 2;
}

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++){
        int x, y;
        scanf("%d%d", &x, &y);
        a[i] = {x, y};
    }
    
    int ans = 0;
    memset(score, 0, sizeof score);
    for(int i = 1; i <= n; i ++){
        int x = a[i].first, y = a[i].second;
        score[check1(x, y)] ++;
    }
    ans = max(ans, score[1]);
    
    memset(score, 0, sizeof score);
    for(int i = 1; i <= n; i ++){
        int x = a[i].first, y = a[i].second;
        score[check2(x, y)] ++;
    }
    ans = max(ans, score[1]);
    
    memset(score, 0, sizeof score);
    for(int i = 1; i <= n; i ++){
        int x = a[i].first, y = a[i].second;
        score[check3(x, y)] ++;
    }
    ans = max(ans, score[1]);
    
    memset(score, 0, sizeof score);
    for(int i = 1; i <= n; i ++){
        int x = a[i].first, y = a[i].second;
        score[check4(x, y)] ++;
    }
    ans = max(ans, score[1]);
    
    memset(score, 0, sizeof score);
    for(int i = 1; i <= n; i ++){
        int x = a[i].first, y = a[i].second;
        score[check5(x, y)] ++;
    }
    ans = max(ans, score[1]);
    
    memset(score, 0, sizeof score);
    for(int i = 1; i <= n; i ++){
        int x = a[i].first, y = a[i].second;
        score[check6(x, y)] ++;
    }
    ans = max(ans, score[1]);
    
    printf("%d\n",ans);
    
    return 0;
}

1789. 牛为什么过马路II

题目链接
https://www.acwing.com/problem/content/1791/

解析

  • 注意读题:AC和BC这种不算交叉
  • 关于交叉的判断,就老老实实描述就行,可以模拟一下相对位置关系,不要偷懒

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 30;

int S[N], E[N];
bool st[N];
char s[N * 2];

int main()
{
    scanf("%s", s);

    for(int i = 0; i < 52; i ++){
        if(!st[s[i] - 'A']){
            S[s[i] - 'A'] = i;
            st[s[i] - 'A'] = true;
        }
        else{
            E[s[i] - 'A'] = i;
        }
    }
    
    for(int i = 0; i < 26; i ++){
        if(S[i] > E[i]){
            swap(S[i], E[i]);
        }
    }
    
    int cnt = 0;
    for(int i = 0; i < 26; i ++){
        for(int j = i + 1; j < 26; j ++){
            if(S[i] < S[j] && E[i] > S[j] && E[i] < E[j]) cnt ++;
            else if(S[j] < S[i] && E[j] > S[i] && E[j] < E[i]) cnt ++;
        }
    }
    
    printf("%d\n", cnt);
    
    return 0;
}

1776. 牛的基因组学

题目链接
https://www.acwing.com/problem/content/1778/

解析
暴力

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110;

bool cow1[N][5], cow0[N][5]; //ATCG
char a[N];
int n, m;

int main()
{
    scanf("%d%d", &n, &m);
    
    for(int i = 0; i < n; i ++){
        scanf("%s", a);
        for(int j = 0; j < m; j ++){
            if(a[j] == 'A') cow1[j][0] = true;
            else if(a[j] == 'T') cow1[j][1] = true;
            else if(a[j] == 'C') cow1[j][2] = true;
            else if(a[j] == 'G') cow1[j][3] = true;
        }
    }
    
    for(int i = 0; i < n; i ++){
        scanf("%s", a);
        for(int j = 0; j < m; j ++){
            if(a[j] == 'A') cow0[j][0] = true;
            else if(a[j] == 'T') cow0[j][1] = true;
            else if(a[j] == 'C') cow0[j][2] = true;
            else if(a[j] == 'G') cow0[j][3] = true;
        }
    }
    
    int cnt = 0;
    for(int i = 0; i < m; i ++){
        bool flag = true;
        for(int k = 0; k < 4; k ++){
            if(cow1[i][k] && cow0[i][k]) flag = false;
        }
        if(flag) {
            cnt ++;   
        }
    }

    printf("%d\n", cnt);
    
    return 0;
}

1762. 牛的洗牌

题目链接
https://www.acwing.com/problem/content/1764/

解析
暴力。
题目稍微有点歧义,三次洗牌指令相同,即要操作三次。

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110;

int a[N];
string ans[N], b[N];
int n;

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
    for(int i = 1; i <= n; i ++){
        string str;
        cin >> str;
        b[i] = str;
    }
    
    for(int i = 1; i <= n; i ++) ans[i] = b[a[i]]; 

    for(int i = 1; i <= n; i ++) b[i] = ans[a[i]]; 

    for(int i = 1; i <= n; i ++) ans[i] = b[a[i]]; 

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

1750. 救生员

题目链接
https://www.acwing.com/activity/content/problem/content/6573/

*解析
理清思路直接写就行,没什么算法

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110;

typedef pair<int, int> PII;

int n;
PII a[N];

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++){
        int x, y;
        scanf("%d%d", &x, &y);
        a[i] = {x, y};
    }
    sort(a + 1, a + n + 1);
    
    int res = 0;
    for(int i = 1; i <= n; i ++){
        int ans = 0;
        int st = 0, ed = 0;
        for(int j = 1; j <= n; j ++){
            if(j == i) continue;
            else{
                if(a[j].first <= ed) ed = max(ed, a[j].second);
                else{
                    ans += (ed - st);
                    st = a[j].first, ed = a[j].second;
                }
            }
        }
        ans += (ed - st);
        res = max(res, ans);
    }
    
    printf("%d\n", res);
    
    return 0;
}

1726. 挤奶顺序

题目链接
https://www.acwing.com/problem/content/description/1728/

解析
分类讨论:

  • 奶牛1的位置确定
  • 奶牛1的相对位置确定
  • 奶牛1的位置和相对位置都不确定

第一种情况直接输出。
对于后两种情况,只考虑对相对位置给定的奶牛进行排序,在这些奶牛中,某些奶牛的位置可能是确定的,如果奶牛1的相对位置确定,则剩余相对位置确定而位置不确定的奶牛应该尽量往前排;如果奶牛1的相对位置不确定,则剩余相对位置确定而位置不确定的奶牛应该尽量往后排。

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110;

int n, m, k;
int pos[N];
int a[N], b[N];
bool st[N];

int main()
{
    scanf("%d%d%d", &n, &m, &k);
    bool flag = true;
    for(int i = 1; i <= m; i ++) {
        scanf("%d", &a[i]);
        if(a[i] == 1) flag = false;
    }
    
    for(int i = 0; i < k; i ++){
        int x, y;
        scanf("%d%d", &x, &y);
        pos[x] = y;
        st[y] = true;
        //cout << x << ' ' << y << endl; 
    }
    
    if(pos[1] != 0) printf("%d\n", pos[1]);
    else if (flag) {
        int idx = n;
        for(int i = m; i > 0; i --){
            if(pos[a[i]] != 0) {
                idx = pos[a[i]] - 1;
            }
            else {
                while(st[idx]) idx --;
                pos[a[i]] = idx --;
            }
        }
        //for(int i = 1; i <= m; i ++) printf("%d ", pos[a[i]]);
        //puts("");
        for(int i = 1; i <= n; i ++) b[pos[i]] = i;
        int ans = 0;
        for(int i = 1; i <= n; i ++){
            if(b[i] == 0){
                ans = i;
                break;
            }
        }
        printf("%d\n", ans);
    }
    else if(!flag){
        
        int idx = 1;
        for(int i = 1; i <= m; i ++){
            if(pos[a[i]] != 0) {
                idx = pos[a[i]] + 1;
            }
            else {
                while(st[idx]) idx ++;
                pos[a[i]] = idx ++;
            }
        }
        int ans = pos[1];
        printf("%d\n", ans);
    }
    
    return 0;
}

1696. 困牛排序

题目链接
https://www.acwing.com/problem/content/1698/

解析
数据范围100,写暴力就行,不要去想什么性质然后O(n)完成,没必要也没有,详情可见wa掉的例子。

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110;

int n;
int a[N];

bool check(int l, int r){
    bool flag = true;
    for(int i = l; i <= r; i ++){
        if(a[i] > a[i + 1]) flag = false;
    }
    if(flag) return true;
    return false;
}

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++) {
        scanf("%d", &a[i]);
    }
    
    int ans = 0;
    a[n + 1] = 0x3f3f3f3f;
    for(int i = 1; i <= n; i ++){
        if(check(i, n)) break;
        else ans ++;
    }
    
    printf("%d\n", ans);
    
    return 0;
}

1684. 大型植被恢复

题目链接
https://www.acwing.com/problem/content/1686/

解析

  • 建图
  • 搜索答案的顺序

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 200;

int n, m;
int e[N], ne[N], h[N], idx;
bool st[5];
int ans[N], du[N];

void add(int a, int b){
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

int main()
{
    scanf("%d%d", &n, &m);
    memset(h, -1, sizeof h);
    while(m --){
        int l, r;
        scanf("%d%d", &l, &r);
        if(r < l) swap(l, r);
        add(r, l);
        du[r] ++;
    }
    
    for(int i = 1; i <= n; i ++){
        if(du[i] == 0) {
            ans[i] = 1;
        }
        else{
            memset(st, 0, sizeof st);
            for(int j = h[i]; j != -1; j = ne[j]){
                int k = e[j];
                st[ans[k]] = true;
            }
            for(int j = 1; j <= 4; j ++){
                if(!st[j]){
                    ans[i] = j;
                    break;
                }
            }
        }
    }
    for(int i = 1; i <= n; i ++) 
        if(!ans[i]) ans[i] = 1;
    for(int i = 1; i <= n; i ++) printf("%d", ans[i]);
    puts("");
    
    return 0;
}

1460. 我在哪?

题目链接
https://www.acwing.com/problem/content/1462/

解析
写暴力,8好意思,感觉这种找最小值的也不太用二分,直接从最小的开始遍历就行。

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>

using namespace std;

const int N = 110;

int n;
string a;
map<string, bool> st;

bool check(int x){
    for(int i = 0; i + x - 1 < n; i ++){
        string s = "";
        for(int j = 0; j < x; j ++) s = s + a[i + j];
        //cout << s << endl;
        if(st[s]) return false;
        st[s] = true;
    }
    return true;
}

int main()
{
    scanf("%d", &n);
    cin >> a;
    
    int ans = 0;
    for(int i = 1; i <= n; i ++){
        if(check(i)){
            ans = i;
            break;
        }
    }
    printf("%d\n", ans);
    
    return 0;
}

1443. 拍照

题目链接
https://www.acwing.com/problem/content/1445/

解析
初次思考不够细致,题目判断条件有两个:

  • a中各个数组不重复
  • a中各个数字为正数

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1010;

int n;
int a[N], b[N];
bool st[N];

int main()
{
    scanf("%d", &n);
    for(int i = 1; i < n; i ++) scanf("%d", &b[i]);
    
    for(int i = b[1] - 1; i > 0; i --){
        memset(st, 0, sizeof st);
        a[1] = i;
        bool flag = true;
        for(int i = 2; i <= n; i ++){
            int x = b[i - 1] - a[i - 1];
            if(x <= 0) {
                flag = false;
                break;
            }
            else if(st[x]){
                flag = false;
                break;
            }
            else {
                a[i] = x;
                st[x] = true;
            };
        }
        if(flag) break;
    }
    
    for(int i = 1;  i <= n; i ++) printf("%d ", a[i]);
    puts("");
    
    return 0;
}

1672. 疯狂的科学家

题目链接
https://www.acwing.com/problem/content/1674/

解析
写得很顺利是因为实现类似功能的代码段我写过。
贪心题。

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1010;

int n;
char a[N], b[N];

int main()
{
    scanf("%d", &n);
    scanf("%s%s", a, b);
    
    int cnt = 0;
    for(int i = 0; i < n;){
        int x = i;
        while(a[x] != b[x]) x ++;
        if(x != i) cnt ++;
        while(a[x] == b[x]) x ++;
        i = x;
    }
    
    printf("%d\n", cnt);
    
    return 0;
}

1660. 社交距离II

题目链接
https://www.acwing.com/problem/content/1662/

解析
思路没错,就是代码写错了,真心建议怎么改也改不出来就输出中间结果模拟样例。枯萎ing...

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef pair<int, int> PII;

const int N = 1010;

int n;
PII a[N], b;

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++){
        int x, y;
        scanf("%d%d", &x, &y);
        a[i] = {x, y};
    }
    sort(a + 1, a + n + 1);
    
    int dmax = 0x3f3f3f3f;
    for(int i = 1; i < n; i ++){
        if((!a[i].second && a[i + 1].second) || (a[i].second && !a[i + 1].second)){
            dmax = min(dmax, a[i + 1].first - a[i].first);
        }
    }
    
    dmax --;
    
    int cnt = 0;
    int last = - 0x3f3f3f3f;
    for(int i = 1; i <= n; i ++){
        if(!a[i].second) {
            continue;
        }
        if(a[i].first - last > dmax) {
            last = a[i].first;
            cnt ++;
        }
        else{
            last = a[i].first;
        }
    }
    
    printf("%d\n", cnt);
    
    return 0;
}

3347. 菊花链

题目链接
https://www.acwing.com/problem/content/3350/

解析
前缀和+暴力

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110;

int n;
int a[N], s[N];

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
    for(int i = 1; i <= n; i ++) s[i] = s[i - 1] + a[i];
    
    int cnt = 0;
    for(int i = 1; i <= n; i ++){
        for(int j = i; j <= n; j ++){
            int sum = s[j] - s[i - 1];
            if(sum % (j - i + 1) == 0){
                int p = sum / (j - i + 1);
                for(int k = i; k <= j; k ++){
                    if(a[k] == p){
                        cnt ++;
                        break;
                    }
                }
            }
        }
    }
    printf("%d\n", cnt);
    
    return 0;
}

1978. 奶牛过马路

题目链接
https://www.acwing.com/problem/content/1980/

解析
首先按照pair的第一维(x)排序,然后维护最大前缀和和最小后缀和,一条路径是安全的等价与这条路径对应的y大于它前面数的最大前缀和后面数的最小后缀。

Ac代码

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>

using namespace std;

typedef pair<int, int> PII;

const int N = 1e5 + 10;

int n;
PII a[N];
int m[N];

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++){
        int x, y;
        scanf("%d%d", &x, &y);
        a[i] = {x, y};
        st[y] = false;
    }
    sort(a + 1, a + n + 1);
    
    int ans = 0;
    int sum = 0;
    m[0] = -0x3f3f3f3f;
    for(int i = 1; i <= n; i ++) m[i] = max(m[i - 1], a[i].second);
    for(int i = 1; i <= n;){
        int cnt = 0;
        int x = m[i];
        //printf("%d %d ", i, x);
        while(m[i] == x) {
            i ++, cnt ++;
        }
        printf("%d\n", cnt);
        sum += cnt;
        if(cnt == 1) ans ++;
    }
    printf("%d\n", ans);
    
    return 0;
}
posted @   小菜珠的成长之路  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示