写在前面的话:
这次比赛的题目把我惊艳到了,题目质量非常高,给出题人点个赞!
A
知识点:模拟。
参考cf难度:1500
这道题其实读懂题,按题意模拟就可以了。数据很小,所以每次操作直接排序即可。要注意的是每个学生能力值改变的时间点不要搞错了。
复杂度: O ( n 2 l o g n ) O(n^2logn) O(n2logn)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct node{
ll id,val,p;
};
node a[2000];
bool cmp(node a,node b){
if(a.val!=b.val)return a.val>b.val;
return a.id<b.id;
}
int main(){
int t,i;
int b;
int n,r,l;
cin>>n>>r>>l;
for(i=0;i<n;i++)cin>>a[i].id;
for(i=0;i<n;i++)cin>>a[i].val;
for(i=0;i<n;i++)cin>>a[i].p;
int len=n;
while(len>1){
sort(a,a+len,cmp);
for(i=0;i<10;i++)a[i].val+=r;
len=len/2+len%2;
if(len==1)break;
if(len>=6){
for(i=0;i<3;i++)a[i].val-=l;
}
for(i=0;i<len;i++)a[i].val+=a[i].p;
}
cout<<a[0].id<<" "<<a[0].val;
}
B
知识点:状压搜索/DFS
参考cf难度:2100
第一次想到的算法是贪心:枚举每个度数 i i i,先顺时针到 i i i再逆时针;或者先逆时针到 i i i再顺时针,结果wa了,甚至一度怀疑题目出问题了。
后面发现这个算法是错的,有可能出现先逆时针,再顺时针,再逆时针的情况(因为每个点的 t t t是不同的,所以不能简单的去贪心)。正确做法是枚举每一次选择顺时针或者逆时针,这样一共有 n n n次决策,总决策方案就是 2 n 2^n 2n种。
复杂度: O ( n ∗ 2 n ) O(n*2^n) O(n∗2n)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
double xa,ya,xb,yb,xc,yc,xd,yd;
struct node{
int w,v;
};
bool cmp(node a,node b){
return a.w<b.w;
}
node a[22];
ll tong[361];
int main(){
int t,i,j;
int b;
int n,r,l;
int x,y;
cin>>n>>x>>y;
for(i=0;i<n;i++){
ll w,v;
cin>>w>>v;
a[i].w=w;
a[i].v=v;
tong[w]=max(tong[w],v);
}
sort(a,a+n,cmp);
ll mi=1e12;
if(y<a[0].w){
l=n-1,r=0;
}
else{
for(i=0;i<n;i++){
if(y<a[i].w)break;
}
l=i-1,r=i%n;
}
// cout<<l<<" "<<r<<endl;
for(i=0;i<1<<n;i++){
int templ=l,tempr=r,st=y;
ll p=