Codeforces Round #813 (Div. 2)

 
复制代码
#include<bits/stdc++.h>
using namespace std;

const int maxn = 120;
int a[maxn];

void solve() {
    int n,k;
    cin >> n >> k;
    int cnt = k;
    for(int i = 1; i <= n; i ++) {
        cin >> a[i];
        if(i <= k && a[i] <= k) cnt --;
    }
    cout << cnt << "\n";
}
int main() 
{
    int t;  cin >> t;
    while(t --) {
        solve();
    }
    return 0;
}
复制代码

 

1712B - Woeful Permutation

题意:确定序列 P{p1, p2 ... pn}中 1-n 的排列顺序,使得 lcm(1,p1)+lcm(2,p2)+…+lcm(n,pn) 最大。  lcm:最小公倍数

 
复制代码
#include<bits/stdc++.h>
using namespace std;

void solve() {
    int n;
    cin >> n;
    stack<int> s;
    if(n % 2 == 0) {
        for(int i = n; i >= 1; i --) {
            if(i % 2 == 0) s.push(i - 1);
            else s.push(i + 1);
        }
    }
    else {
        for(int i = n; i > 1; i --) {
            if(i % 2 == 0)  s.push(i + 1);
            else s.push(i - 1);
        }
        s.push(1);
    }
    while(!s.empty()) {
        cout << s.top() << " ";
        s.pop();
    }
    cout << "\n";
}

int main() 
{
    ios::sync_with_stdio(false); std::cin.tie(nullptr);
    
    int t; cin >> t;
    while(t --) {
        solve();
    }
    
    return 0;
}
复制代码

 

1712C - Sort Zero

题意:给定一个长度为 n 的序列,每次可以选定一个数字,将序列中的所有该数字变为 0 ,问最少需要操作多少次可以将序列变为不下降序列。

 
 题解一:
  对前面数字的修改(->0) 会影响后面的相同的数字,导致可能出现新的不合法情况;每次修改时对所有位置的该相同数字进行遍历,如果一开始就不合法,np --,即假设修改后合法了, 如果修改为0后不合法, np++, 增加不合法数。np是关键
 
复制代码
#include<bits/stdc++.h>
using namespace std;
int n;

void solve() {
    cin >> n;
    vector<int> a(n + 1);
    vector<vector<int>> pos(n + 1);
    
    for (int i = 1; i <= n; i ++) {
        cin >> a[i];
        pos[a[i]].push_back(i);
    }
    
    int np = 0;//不合法 
    int res = 0;//操作数 
    for (int i = 1; i < n; i ++) {
        if (a[i] > a[i + 1]) {
            np ++;
        }
    }
    for (int i = 1; i <= n && np > 0; i ++) {
        if (a[i] > 0) {
            res ++;
            for (auto j : pos[a[i]]) {
                if (j > 1 && a[j - 1] > a[j]) np --;
                if (j < n && a[j] > a[j + 1]) np --;
                
                a[j] = 0;

                if (j > 1 && a[j - 1] > a[j]) np ++;
                if (j < n && a[j] > a[j + 1]) np ++;
                
            }
        }
    }

    cout << res << "\n";
}
int main() {
    int t;
    cin >> t;
    while (t --) {
        solve();
    }

    return 0;
}
复制代码

 

题解二:

  一开始从前往后遍历,如果出现a[i] > a[i + 1]的情况,就把a[i]加入set,然后向前搜索(1),将a[j]插入set,一直到a[j] == 0(初始0)。这样做超时了,我们只需加一句优化,a[i] = 0,即可缩小循环范围,每次搜索到最近的初始为0或修改为0的位置即可。

  感慨一句,set真的很好用,不重不漏,避免了很多思维漏洞问题。用vis数组写了一遍,出了各种各样的bug,找到了原因,但还是没能改出来。比如:找到不满足条件的a[i],在向前遍历前将vis[a[i]]修改为1,如果前面再遇到a[i]就有可能提前结束了搜索,导致res不全 ;如果不修改vis[a[i]],就会出现多次添加的情况。

 

上AC代码

复制代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 50;
int a[maxn];

void solve() {
    int n;
    cin >> n;
    set<int> s;

    for (int i = 1; i <= n; i ++) {
        cin >> a[i];
    }
    for (int i = 1; i < n; i ++) {
        a[i] = s.find(a[i]) == s.end() ? a[i] : 0;
        a[i + 1] = s.find(a[i + 1]) == s.end() ? a[i + 1] : 0;
        if (a[i] > a[i + 1]) {
            int j = i - 1; 
            while(a[j] > 0) {//只相邻还不够,前面的非零都要为0 
                s.insert(a[j]);
                j --;
            }
            s.insert(a[i]);
            a[i] = 0;//加了一个优化, AC了 
        }
    }
    cout << s.size() << "\n";
}

int main() {
    int t;
    cin >> t;
    while (t --) {
        solve();
    }
    return 0;
}
复制代码

 

 vis 数组 wa了
复制代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 50;
int a[maxn];
int vis[maxn];
//WA 
void solve() {
    int n;
    cin >> n;
    map<int, int> mp;
    int re = 0;
    memset(vis, 0, sizeof(vis));
    for (int i = 1; i <= n; i ++) {
        cin >> a[i];
        mp[a[i]] = i;
    }
    for (int i = 1; i < n; i ++) {
        if(vis[a[i]]) a[i] = 0;
        if(vis[a[i + 1]]) a[i + 1] = 0;
        if (a[i] > a[i + 1]) {
            vis[a[i]] = 1;
            re ++;
            int j = i - 1; 
            if(vis[a[j]]) a[j] = 0;
            while(a[j] > 0) {//只相邻还不够,前面的非零都要为0 
                re ++;
                vis[a[j]] = 1;
                j --;
                if(vis[a[j]]) a[j] = 0; //如遇到a[i],会中途断掉,但是如果不加这个判断,就会多次添加res,WA   模拟:1 2 4 4 0  2就会搜索不到
            }
            
        }
    }
    cout << re << "\n";
}

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

    return 0;
}
复制代码

 

 
 
posted @   Y2ZH  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示