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