Codeforces Round #503 (by SIS, Div. 2)
https://codeforces.com/contest/1020
A
1 #include <iostream> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 #include <cstdio> 6 #include <cstdlib> 7 #include <string.h> 8 using namespace std; 9 int n,h,a,b,k; 10 int main() 11 { 12 scanf("%d%d%d%d%d",&n,&h,&a,&b,&k); 13 while(k--) 14 { 15 int ta,fa,tb,fb;long long ans=0; 16 scanf("%d%d%d%d",&ta,&fa,&tb,&fb); 17 if(ta==tb) 18 ans+=abs(fb-fa); 19 if(ta!=tb) 20 { 21 ans+=abs(tb-ta); 22 if(fa>=a and fa<=b) 23 { 24 ans+=abs(fb-fa); 25 } 26 else 27 { 28 if(abs(fa-a)<abs(fa-b)) 29 { 30 ans+=abs(fa-a); 31 ans+=abs(a-fb); 32 } 33 else 34 { 35 ans+=abs(fa-b); 36 ans+=abs(b-fb); 37 } 38 } 39 } 40 cout<<ans<<endl; 41 } 42 return 0; 43 }
B
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<string> 6 #include<queue> 7 #include<cmath> 8 using namespace std; 9 10 int a[1005]; 11 bool book[1005]; 12 13 int main(){ 14 15 int n; 16 cin>>n; 17 memset(book,0,sizeof(book)); 18 for(int i=1;i<=n;i++){ 19 cin>>a[i]; 20 } 21 for(int i=1;i<=n;i++){ 22 memset(book,0,sizeof(book)); 23 int j=i; 24 while(!book[j]){ 25 book[j]=true; 26 j=a[j]; 27 } 28 cout<<j<<" "; 29 } 30 cout<<endl; 31 32 }
C
贪心
题意:给定n和m,分别为选民和政党的数量,你事先知道每一个选民将要挑选的政党,但是你可以花钱收买他,求你最少花费多少钱可以赢得选举
思路:从小到大枚举自己最终的选票,对于选票比自己多的政党,就从小到大收买,直到比自己小为止,全部买完还没达到自己所枚举的票数,就从小到大收买其他人的
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<string> 6 #include<cmath> 7 #include<queue> 8 #include<map> 9 #include<vector> 10 using namespace std; 11 12 struct sair{ 13 int pos; 14 long long b; 15 }a[3005]; 16 int vis[3005]; 17 int num[3005]; 18 19 bool cmp(sair a,sair b){ 20 return a.b<b.b; 21 } 22 23 int main(){ 24 std::ios::sync_with_stdio(false); 25 int n,m; 26 cin>>n>>m; 27 for(int i=1;i<=n;i++){ 28 cin>>a[i].pos>>a[i].b; 29 } 30 long long ans=0x3f3f3f3f3f3f3f3f; 31 sort(a+1,a+n+1,cmp); 32 for(int i=0;i<=n;i++){ 33 long long sum=0; 34 memset(vis,0,sizeof(vis)); 35 memset(num,0,sizeof(num)); 36 for(int j=n;j>=1;j--){ 37 if(num[a[j].pos]<i||a[j].pos==1){ 38 num[a[j].pos]++; 39 } 40 else{ 41 sum+=a[j].b; 42 vis[j]=1; 43 num[1]++; 44 } 45 } 46 for(int j=1;j<=n;j++){ 47 if(num[1]<=i&&a[j].pos!=1&&!vis[j]){ 48 sum+=a[j].b; 49 num[1]++; 50 } 51 } 52 if(num[1]>i) 53 ans=min(ans,sum); 54 } 55 cout<<ans<<endl; 56 57 }
D
交互题(感觉这类都是二分题?)
题意:n个人围成一圈(n为偶数),每个人手上有一个数字,相邻的两个人相差1或-1。问是否存在一个人与他对面的人手上的数字相同
思路:模拟了半天才发现,当n%4==2时,无解,n%4==0时,设i位置与对面的差值为a[i],可以发现a[i]和a[(mid+n/2-1)%n+1]要么是相反数要么为0,当a[i]和a[(mid+n/2-1)%n+1]是相反数时,它们之间一定存在a[i]=0,那就是答案
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 sqr(x) ((x)*(x)) 6 #define pb push_back 7 #define eb emplace_back 8 #define maxn 1005 9 #define eps 1e-8 10 #define pi acos(-1.0) 11 #define rep(k,i,j) for(int k=i;k<j;k++) 12 typedef long long ll; 13 typedef pair<int,int> pii; 14 typedef pair<double,double>pdd; 15 typedef pair<int,char> pic; 16 typedef pair<pair<int,string>,pii> ppp; 17 typedef unsigned long long ull; 18 const long long MOD=998244353; 19 const double oula=0.57721566490153286060651209; 20 using namespace std; 21 22 int n; 23 vector<int>ve; 24 int x; 25 26 int query(int x){ 27 cout<<"? "<<x<<endl; 28 cin>>x; 29 return x; 30 } 31 32 int main(){ 33 std::ios::sync_with_stdio(false); 34 cin>>n; 35 if(n%4==0){ 36 int L=1,R=n/2,mid; 37 int tmp1=query(1); 38 int tmp2=query(1+n/2); 39 if(tmp1==tmp2){ 40 cout<<"! "<<1<<endl; 41 return 0; 42 } 43 int flag1=tmp1>tmp2?1:-1; 44 int flag2=-flag1; 45 while(L<=R){ 46 mid=L+R>>1; 47 tmp1=query(mid); 48 tmp2=query((mid+n/2-1)%n+1); 49 if(tmp1==tmp2){ 50 cout<<"! "<<mid<<endl; 51 return 0; 52 } 53 if(flag1<0){ 54 if(tmp1<tmp2) L=mid+1; 55 else R=mid-1; 56 } 57 else{ 58 if(tmp1<tmp2) R=mid-1; 59 else L=mid+1; 60 } 61 } 62 tmp1=query(R); 63 tmp2=query((R+n/2-1)%n+1); 64 if(tmp1==tmp2){ 65 cout<<"! "<<R<<endl; 66 } 67 tmp1=query(L); 68 tmp2=query((L+n/2-1)%n+1); 69 if(tmp1==tmp2){ 70 cout<<"! "<<L<<endl; 71 } 72 } 73 else{ 74 cout<<"! -1"<<endl; 75 return 0; 76 } 77 78 }
E
题意:有向图中找到一个点集,使得点集内的点满足dist(x,y)>=2,存在一个点集内的点到点集外的点dist(x,y)<=2
思路:遍历每个点,把他相邻的点删去。然后再判断留下来的点是否相邻(看到这题的第一个想法,但是正确性不会证明。。。)
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 sqr(x) ((x)*(x)) 6 #define pb push_back 7 #define eb emplace_back 8 #define maxn 1005 9 #define eps 1e-8 10 #define pi acos(-1.0) 11 #define rep(k,i,j) for(int k=i;k<j;k++) 12 typedef long long ll; 13 typedef pair<int,int> pii; 14 typedef pair<double,double>pdd; 15 typedef pair<int,char> pic; 16 typedef pair<pair<int,string>,pii> ppp; 17 typedef unsigned long long ull; 18 const long long MOD=998244353; 19 const double oula=0.57721566490153286060651209; 20 using namespace std; 21 22 vector<int>ve[1000005]; 23 bool book[1000005]; 24 bool used[1000005]; 25 26 int main(){ 27 std::ios::sync_with_stdio(false); 28 int n,m; 29 cin>>n>>m; 30 int u,v; 31 for(int i=1;i<=m;i++){ 32 cin>>u>>v; 33 ve[u].pb(v); 34 } 35 for(int i=1;i<=n;i++){ 36 if(!book[i]){ 37 book[i]=1; 38 used[i]=1; 39 for(int j=0;j<ve[i].size();j++){ 40 book[ve[i][j]]=1; 41 } 42 } 43 } 44 int ans=0; 45 for(int i=n;i;i--){ 46 if(used[i]){ 47 ans++; 48 for(int j=0;j<ve[i].size();j++){ 49 used[ve[i][j]]=0; 50 } 51 } 52 } 53 cout<<ans<<endl; 54 for(int i=1;i<=n;i++){ 55 if(used[i]){ 56 cout<<i<<" "; 57 } 58 } 59 }