Codeforces Round #595 (Div. 3)
比赛传送门
A - Yet Another Dividing into Teams
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define VI vector<int>
const int N=105;
const int MOD=1e9+7;
int num[N];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
rep(i,1,n)
scanf("%d",&num[i]);
sort(num+1,num+1+n);
vector<int> G;
G.push_back(num[1]);
rep(i,2,n)
{
int len=G.size();
int flag=0;
rep(j,0,len-1)
{
if(num[i]-G[j]>1)
{
G[j]=num[i];
flag=1;
break;
}
}
if(flag==0)
{
G.push_back(num[i]);
}
sort(G.begin(),G.end());
}
printf("%d\n",G.size());
}
return 0;
}
B - Books Exchange
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define VI vector<int>
const int N=2e5+5;
const int MOD=1e9+7;
int num[N];
int vis[N];
int ans[N];
void init()
{
memset(vis,0,sizeof(vis));
}
int dfs(int x,int cnt)
{
if(vis[x]==1)
return cnt;
vis[x]=1;
ans[x]=dfs(num[x],cnt+1);
return ans[x];
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
int n;
scanf("%d",&n);
rep(i,1,n)
{
scanf("%d",&num[i]);
}
rep(i,1,n)
{
dfs(i,0);
}
rep(i,1,n)
{
printf("%d ",ans[i]);
}
printf("\n");
}
return 0;
}
C - Good Numbers
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define VI vector<int>
const int N=2e5+5;
const int MOD=1e9+7;
ll num[N];
int vis[N];
void init()
{
num[0]=1;
rep(i,1,38)
{
num[i]=num[i-1]*3;
}
}
ll quick_pow(ll a,ll b)
{
ll ret=1;
while(b)
{
if(b&1) ret=ret*a;
a=a*a;
b>>=1;
}
return ret;
}
int main()
{
init();
int T;
scanf("%d",&T);
while(T--)
{
ll n;
scanf("%I64d",&n);
ll nn=0;
rep(i,0,38)
{
if(nn>=n)
break;
nn+=num[i];
}
per(i,38,0)
{
if(nn-num[i]>=n)
nn-=num[i];
}
printf("%I64d\n",nn);
}
return 0;
}
D - Too Many Segments
题意
给定n条线段,在数轴上进行涂色,但是数轴上任意一个点涂色的层数不能超过k,问最少需要删掉哪几条线段。
思路
按照左端点排序后,依次向数轴上涂色,并记录层数,如果某次涂色后层数超过k,则删去右端点最大的那条线段。
坑点
想不到
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
const int N=2e5+5;
vector<PII> G[N];
vector<int> ANS;
set<PII> s;
int main()
{
int n,k,l,r;
scanf("%d%d",&n,&k);
rep(i,1,n)
{
scanf("%d%d",&l,&r);
G[l].push_back(make_pair(r,i));
}
rep(i,1,N-1)
{
while(!s.empty()&&s.begin()->first<i)
s.erase(s.begin());
int lenn=G[i].size();
rep(j,0,lenn-1)
s.insert(G[i][j]);
lenn=s.size();
while(lenn>k)
{
ANS.push_back(prev(s.end())->second);
s.erase(prev(s.end()));
lenn--;
}
}
sort(ANS.begin(),ANS.end());
int len=ANS.size();
printf("%d\n",len);
rep(i,0,len-1)
printf("%d ",ANS[i]);
printf("\n");
return 0;
}
E - By Elevator or Stairs?
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define VI vector<int>
const int N=2e5+5;
const int MOD=1e9+7;
int a[N],b[N];
ll dp[N][2];
int main()
{
int n,c;
scanf("%d%d",&n,&c);
rep(i,1,n-1) scanf("%d",&a[i]);
rep(i,1,n-1) scanf("%d",&b[i]);
dp[1][0]=c;
dp[1][1]=0;
rep(i,2,n)
{
dp[i][0]=min(dp[i-1][0]+b[i-1],dp[i-1][1]+c+b[i-1]);
dp[i][1]=min(dp[i-1][0]+a[i-1],dp[i-1][1]+a[i-1]);
// cout<<"DEBUG: "<<dp[i][0]<<' '<<dp[i][1]<<endl;
}
rep(i,1,n)
{
printf("%I64d ",min(dp[i][0],dp[i][1]));
}
return 0;
}