Codeforces Round #500 (Div. 2) [based on EJOI]
https://codeforces.com/contest/1013
A
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define IT set<node>::iterator 6 #define sqr(x) ((x)*(x)) 7 #define pb push_back 8 #define eb emplace_back 9 #define maxn 200005 10 #define eps 1e-8 11 #define pi acos(-1.0) 12 #define rep(k,i,j) for(int k=i;k<j;k++) 13 typedef long long ll; 14 typedef pair<int,int> pii; 15 typedef pair<ll,ll>pll; 16 typedef pair<ll,int> pli; 17 typedef pair<pair<int,string>,pii> ppp; 18 typedef unsigned long long ull; 19 const long long MOD=1e9+7; 20 const double oula=0.57721566490153286060651209; 21 using namespace std; 22 23 24 int n,ans1,ans2; 25 26 int main(){ 27 std::ios::sync_with_stdio(false); 28 cin>>n; 29 int x; 30 for(int i=1;i<=n;i++){ 31 cin>>x; 32 ans1+=x; 33 } 34 for(int i=1;i<=n;i++){ 35 cin>>x; 36 ans2+=x; 37 } 38 if(ans1>=ans2) puts("YES"); 39 else puts("NO"); 40 }
B
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define IT set<node>::iterator 6 #define sqr(x) ((x)*(x)) 7 #define pb push_back 8 #define eb emplace_back 9 #define maxn 200005 10 #define eps 1e-8 11 #define pi acos(-1.0) 12 #define rep(k,i,j) for(int k=i;k<j;k++) 13 typedef long long ll; 14 typedef pair<int,int> pii; 15 typedef pair<ll,ll>pll; 16 typedef pair<ll,int> pli; 17 typedef pair<pair<int,string>,pii> ppp; 18 typedef unsigned long long ull; 19 const long long MOD=1e9+7; 20 const double oula=0.57721566490153286060651209; 21 using namespace std; 22 23 24 int n,x; 25 int a[100005]; 26 int b[100005]; 27 set<int>se1,se2,se3; 28 29 int main(){ 30 std::ios::sync_with_stdio(false); 31 cin>>n>>x; 32 for(int i=1;i<=n;i++){ 33 cin>>a[i]; 34 b[i]=a[i]&x; 35 se1.insert(a[i]); 36 se2.insert(b[i]); 37 } 38 if(se1.size()!=n){ 39 cout<<0<<endl; 40 return 0; 41 } 42 for(int i=1;i<=n;i++){ 43 se1.erase(a[i]); 44 se1.insert(b[i]); 45 if(se1.size()!=n){ 46 cout<<1<<endl; 47 return 0; 48 } 49 se1.erase(b[i]); 50 se1.insert(a[i]); 51 } 52 if(se2.size()!=n){ 53 cout<<2<<endl; 54 return 0; 55 } 56 cout<<-1<<endl; 57 }
C
题意:给你2*n个值,组成n个点,问能覆盖这n个点的最小矩形面积
思路:枚举长度为n的区间,这段区间作为x坐标的范围,然后将这段区间的差值与剩下部分的差值相乘取最小值
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define IT set<node>::iterator 6 #define sqr(x) ((x)*(x)) 7 #define pb push_back 8 #define eb emplace_back 9 #define maxn 200005 10 #define eps 1e-8 11 #define pi acos(-1.0) 12 #define rep(k,i,j) for(int k=i;k<j;k++) 13 typedef long long ll; 14 typedef pair<int,int> pii; 15 typedef pair<ll,ll>pll; 16 typedef pair<ll,int> pli; 17 typedef pair<pair<int,string>,pii> ppp; 18 typedef unsigned long long ull; 19 const long long MOD=1e9+7; 20 const double oula=0.57721566490153286060651209; 21 using namespace std; 22 23 24 int n; 25 ll a[maxn]; 26 27 int main(){ 28 std::ios::sync_with_stdio(false); 29 cin>>n; 30 n*=2; 31 for(int i=1;i<=n;i++) cin>>a[i]; 32 sort(a+1,a+n+1); 33 ll ans=(a[n/2]-a[1])*(a[n]-a[n/2+1]); 34 for(int i=2;i<=n/2+1;i++){ 35 ans=min(ans,(a[n]-a[1])*(a[i+n/2-1]-a[i])); 36 } 37 cout<<ans<<endl; 38 }
D
题意:有一个n*m的矩形,一开始有q个格子上被标记。对于任意两行两列,如果交汇的四个格子中有三个被标记,那么第4个也会被标记。求至少需要手动标记几个格子,才能让整个矩形内的格子都被标记。
题意:当(x1,y1),(x1,y2),(x2,y1)被标记时,(x2,y2)也会被标记,所以用并查集维护,判断有多少个点是没有被标记的
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define IT set<node>::iterator 6 #define sqr(x) ((x)*(x)) 7 #define pb push_back 8 #define eb emplace_back 9 #define maxn 200005 10 #define eps 1e-8 11 #define pi acos(-1.0) 12 #define rep(k,i,j) for(int k=i;k<j;k++) 13 typedef long long ll; 14 typedef pair<int,int> pii; 15 typedef pair<ll,ll>pll; 16 typedef pair<ll,int> pli; 17 typedef pair<pair<int,string>,pii> ppp; 18 typedef unsigned long long ull; 19 const long long MOD=1e9+7; 20 const double oula=0.57721566490153286060651209; 21 using namespace std; 22 23 24 int n,m,q; 25 int fa[maxn*2]; 26 27 int Find(int x){ 28 int r=x,y; 29 while(x!=fa[x]){ 30 x=fa[x]; 31 } 32 while(r!=x){ 33 y=fa[r]; 34 fa[r]=x; 35 r=y; 36 } 37 return x; 38 } 39 40 void join(int x,int y){ 41 int xx=Find(x); 42 int yy=Find(y); 43 if(xx!=yy){ 44 fa[xx]=yy; 45 } 46 } 47 48 int main(){ 49 std::ios::sync_with_stdio(false); 50 cin>>n>>m>>q; 51 int x,y; 52 for(int i=1;i<=n+m;i++) fa[i]=i; 53 for(int i=1;i<=q;i++){ 54 cin>>x>>y; 55 join(x,y+n); 56 } 57 int ans=0; 58 for(int i=1;i<=n+m;i++){ 59 if(fa[i]==i){ 60 ans++; 61 } 62 } 63 cout<<ans-1<<endl; 64 }
E
题意:给你n个数,你一次操作可以把某一个数减一,使任意k个数严格大于它旁边的两个数,问最少需要几次操作。输出1<=k<=(n+1)/2时的答案。
思路: dp[i][j][0]表示表示前i个数有j个满足条件,i、i-1都不满足条件的最少操作数
dp[i][j][1]表示表示前i个数有j个满足条件,i满足条件的最少操作数
dp[i][j][2]表示表示前i个数有j个满足条件,i-1满足条件的最少操作数
然后进行状态转移:
dp[i][j][2]=dp[i-1][j][1]+max(0,a[i]-a[i-1]+1);
dp[i][j][0]=min(dp[i-1][j][0],dp[i-1][j][2]);
dp[i][j][1]=min(dp[i-1][j-1][0]+max(0,a[i-1]-a[i]+1),dp[i-1][j-1][2]+max(0,min(a[i-1],a[i-2]-1)-a[i]+1));
dp[i][j][1]分为两种情况:
1、前两个都不满足条件,那么i-1就是原来的数,即没有被操作过,需要的操作数就是max(0,a[i-1]-a[i]+1)
2、i-2满足条件,那么i-1已经变成了min(a[i-1],a[i-2]-1),还需要的操作数就是max(0,min(a[i-1],a[i-2]-1)-a[i]+1)
因为转移只用到了dp[i-1][j],dp[i-1][j-1],所以可以用滚动数组优化
参考博客:https://ouuan.blog.luogu.org/solution-cf1012c
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define IT set<node>::iterator 6 #define sqr(x) ((x)*(x)) 7 #define pb push_back 8 #define eb emplace_back 9 #define maxn 200005 10 #define eps 1e-8 11 #define pi acos(-1.0) 12 #define rep(k,i,j) for(int k=i;k<j;k++) 13 typedef long long ll; 14 typedef pair<int,int> pii; 15 typedef pair<ll,ll>pll; 16 typedef pair<ll,int> pli; 17 typedef pair<pair<int,string>,pii> ppp; 18 typedef unsigned long long ull; 19 const long long MOD=1e9+7; 20 const double oula=0.57721566490153286060651209; 21 using namespace std; 22 23 24 int n; 25 int dp[2505][3]; 26 int a[5005]; 27 28 int main(){ 29 std::ios::sync_with_stdio(false); 30 cin>>n; 31 for(int i=1;i<=n;i++) cin>>a[i]; 32 for(int i=0;i<=2;i++){ 33 for(int j=0;j<=(n+1)/2;j++){ 34 dp[j][i]=0x3f3f3f3f; 35 } 36 } 37 dp[0][0]=dp[1][1]=0; 38 for(int i=2;i<=n;i++){ 39 for(int j=(i+1)/2;j>=1;j--){ 40 dp[j][2]=dp[j][1]+max(0,a[i]-a[i-1]+1); 41 dp[j][0]=min(dp[j][0],dp[j][2]); 42 dp[j][1]=min(dp[j-1][0]+max(0,a[i-1]-a[i]+1),dp[j-1][2]+max(0,min(a[i-1],a[i-2]-1)-a[i]+1)); 43 } 44 } 45 for(int i=1;i<=(n+1)/2;i++){ 46 cout<<min(dp[i][0],min(dp[i][1],dp[i][2]))<<" "; 47 } 48 }
原文地址:https://www.cnblogs.com/Fighting-sh/p/10595566.html