(ICPC)亚洲区域赛(昆明)赛后补题题解

我没有参加这次比赛 因为太菜了
所以赛后自己试着去写了一下这场的题目 感觉好难啊 如果我去参加这次比赛的话 估计就是打铁的
不知道以后该怎么办了

H. Hard Calculation

签到题

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int maxt=10000;

int main()
{
	int x;
    cin>>x;
	cout<<x+2020<<endl;
return 0;	
 } 

L.Simone and graph coloring

题目大意:有一个序列 我们要对这个序列的每个点都进行染色 在这之前我们会对这个序列中的逆序对进行连线 然后就可以构造成一个图 在染色的时候图中相邻的两个点的颜色不能相同 求最少要用多少种颜色并且输出每个点的颜色(如果有多种可能 随意输出其中一种即可)?

在这个序列中所有的逆序对会连成一张图 没有连线的点(也就是在序列中没有形成逆序对的点)直接全部染成一种颜色即可
在这个图中最少需要用的颜色应该就是 这个序列的最长下降子序列的长度(注意不能相等)
在求最长下降子序列的时候可以直接用lower_bound()函数 求出第一个小于x的数的下标
直接for循环 遇到逆序对的时候直接颜色加一
不是逆序对的时候 就需要在前面找一个与它不是邻居的点(也就是小于它的点 刚好也就可以用到low_bound()函数)
这时候可以与这个点共用一个颜色

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxt=1e6+10;
int n,h[maxt],t,dp[maxt],f[maxt];
//其实就是一个求最长下降子序列的变换
int main()
{
    cin>>t;
    while(t --){
        scanf("%d",&n);
        for(int i=1;i <=n;i ++)
            scanf("%d",&h[i]);
        int ans=1;
        dp[ans]=h[1];
        f[1]=1;       
        for(int i=2;i <=n;i ++){
            if(h[i]<dp[ans]) dp[++ans]=h[i],f[i]=ans;//遇到逆序对时 颜色数直接加一 
            else {
                int r=upper_bound(dp+1,dp+ans+1,h[i],greater<int>())-dp;//在dp数组中查找第一个小于h[i]的值
                f[i]=r;//在逆序对序列中查找不是与h[i]构成逆序对的数 也就是两个数不相邻 使用下标当作颜色就可以
                dp[r]=h[i];
            }
        }
        printf("%d\n",ans);
        for(int i=1;i <=n;i ++)
            cout<<f[i]<<" ";
       printf("\n");
    }
return 0;  
}

关于lower_bound()和upper_bound()

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxt=10000;

int main()
{
	int h[10]={1,2,3,4,5,6,7,8,9};
	int x=upper_bound(h,h+9,7)-h;//在数组中找到第一个大于x的下标 
	int y=lower_bound(h,h+9,7)-h;//在数组中找到第一个大于或等于x的下标 
	cout<<x<<" "<<h[x]<<endl;
	cout<<y<<" "<<h[y]<<endl<<endl;
	
	int k[10]={9,8,7,6,5,4,3,2,1};
	int a=upper_bound(k,k+9,7,greater<int>())-k;//求在k数组中第一个小于7的数的下标 
	int b=lower_bound(k,k+9,7,greater<int>())-k;//求在k数组中第一个小于或等于7的数的下标 
	cout<<a<<" "<<k[a]<<endl;
	cout<<b<<" "<<k[b]<<endl;
return 0;	
 } 
 /*
 7 8 
 6 7 
 
 3 6
 2 7 
 */ 

##  I.Mr. Main and Windmills
待补
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值