Codeforces Global Round 15 +140

本文提供了三道编程竞赛题目的解析及代码实现:A题求最小选择位置使字符串有序;B题找出优于所有人的运动员;C题通过连线最大化交点数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

强打精神打得,以外的还不错。
不过可惜是大号打得,小号的话还能再上一拨分

A 题意

给一个串,选一些位置任意排序,要求选最少位置,使得有序

A 思路

显然本来就有序的就不用选,sort一下比较即可。

A 代码
#include<cstdio>
#include<iostream>
#include<iomanip>
#include<map>
#include<unordered_map>
#include<string>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib> 
#include<chrono>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
//#define int long long
//#define double long double
using namespace std;
	typedef long long ll;
	const int maxn=400505;
	const int inf=0x3f3f3f3f;
	int n,m,k;
	void YES(){
		cout<<"YES"<<endl;
	}
	void NO(){
		cout<<"NO"<<endl;
	}
	void solve(){
        cin>>n;
        string s,y;
        cin>>s;
        y=s;
        sort(y.begin(),y.end());
        int cnt=0;
        for(int i=0;i<s.size();i++){
            if(s[i]!=y[i])
                cnt++;
        }
        cout<<cnt<<endl;
	}
	signed main(){
        IOS
		#ifndef ONLINE_JUDGE
		    freopen("IO\\in.txt","r",stdin);
		    freopen("IO\\out.txt","w",stdout);
        #endif
		int tn=1;
		cin>>tn;
		while(tn--){
			solve();
		}
	} 
	
						
B 题意

每个人有五个数代表排名,如果一个运动员有3个以上排名比另一个更靠前,则他是优于另一个运动员。找出优于所有人的运动员

B 思路

赛场猜结论,赛后看见的证明。
可以证明最多只有一个最优运动员。
sort排序一下,再单独判断一下运动员是否是最优即可。

B 代码
#include<cstdio>
#include<iostream>
#include<iomanip>
#include<map>
#include<unordered_map>
#include<string>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib> 
#include<chrono>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
//#define int long long
//#define double long double
using namespace std;
	typedef long long ll;
	const int maxn=400505;
	const int inf=0x3f3f3f3f;
	int n,m,k;
	void YES(){
		cout<<"YES"<<endl;
	}
	void NO(){
		cout<<"NO"<<endl;
	}
    struct Node{
        int rk[5];
        int id;
    }node[maxn];
    bool cmp(Node a,Node b){
        int cnt=0;
        for(int i=0;i<5;i++)
            if(a.rk[i]<b.rk[i]) cnt++;
        if(cnt>=3)  return 1;
        return 0;
    }
	void solve(){
        cin>>n;
        for(int i=1;i<=n;i++){
            for(int j=0;j<5;j++)
                cin>>node[i].rk[j];
            node[i].id=i;
        }
        sort(node+1,node+1+n,cmp);
        for(int i=2;i<=n;i++){
            int c=0;
            for(int j=0;j<5;j++)
                if(node[1].rk[j]<node[i].rk[j]) c++;
            if(c<3){
                cout<<-1<<endl;
                return ;
            }
        }
        cout<<node[1].id<<endl;
	}
	signed main(){
        IOS
		#ifndef ONLINE_JUDGE
		    freopen("IO\\in.txt","r",stdin);
		    freopen("IO\\out.txt","w",stdout);
        #endif
		int tn=1;
		cin>>tn;
		while(tn--){
			solve();
		}
	} 
	
						
C 题意

给出一个圆,上有2n点,给出m代表有m个连线,让你继续连线,共连n条线使得每个点都被连1次。这个圆有神奇的性质,任意三条线不会交于一点。

C 思路

同样是猜结论+赛后补证明。

可以知道,初始的连线我们无法改变,我们需要最大化我们新加的线的交点。
因为那个神奇的性质,所以只要两个线相交,就会有交点。
我们记录一下所有没联线的点,将他们排序,之后将这个数组劈成两半,前后一一对应选,比如8个数,那就1-5,2-6,3-7,4-8这么连。
再n²判断答案即可。

C 代码
#include<cstdio>
#include<iostream>
#include<iomanip>
#include<map>
#include<unordered_map>
#include<string>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib> 
#include<chrono>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
//#define int long long
//#define double long double
using namespace std;
	typedef long long ll;
	const int maxn=400505;
	const int inf=0x3f3f3f3f;
	int n,m,k;
    int cnt[maxn];
    pair<int,int>p[maxn];
    vector<int>v;
	void solve(){
        cin>>n>>m;
        v.clear();
        k=n-m;
        n*=2;
        for(int i=1;i<=n;i++)   cnt[i]=1;
        for(int i=1;i<=m;i++){
            int a,b;
            cin>>a>>b;
            if(a>b) swap(a,b);
            p[i]={a,b};
            cnt[a]--,cnt[b]--;
        }
        int last=1;
        while(last<=n){
            while(!cnt[last])   last++;
            if(last>n)  break;
            v.push_back(last);
            cnt[last]=0;last++;
        }
        for(int i=1;i<=k;i++){
            int a,b;
            a=v[i-1],b=v[i-1+k];
            p[i+m]={a,b};
        }
        sort(p+1,p+1+k+m);
        int ans=0;
        for(int i=1;i<=k+m;i++){
            for(int j=i+1;j<=k+m;j++){
                if(p[j].first<p[i].second&&p[i].second<p[j].second) 
                    ans++;
            }
        }
        cout<<ans<<endl;
	}
	signed main(){
        IOS
		#ifndef ONLINE_JUDGE
		    freopen("IO\\in.txt","r",stdin);
		    freopen("IO\\out.txt","w",stdout);
        #endif
		int tn=1;
		cin>>tn;
		while(tn--){
			solve();
		}
	} 
	
						

等待更新

D 题意
D 思路
D 代码
在这里插入代码片
E 题意
E 思路
E 代码
在这里插入代码片
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值