The 2016 ACM-ICPC Asia Dalian Regional Contest
一共a了6题
A:找二分图,判断有没有冲突或者孤立的店
题解:直接dfs即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cassert> #include<iomanip> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const double g=10.0,eps=1e-7; const int N=1000+10,maxn=1000+10,inf=0x3f3f3f; int color[N],n; vector<int>v[N]; bool dfs(int u,int c) { color[u]=c; for(int i=0;i<v[u].size();i++) { int x=v[u][i]; if(color[x]==c||(color[x]==0&&!dfs(x,3-c))) return 0; } return 1; } void solve() { for(int i=1; i<=n; i++) { if(color[i]==1&&!dfs(i,1)) { cout<<"NO"<<endl; return ; } else if(color[i]==2&&!dfs(i,2)) { cout<<"NO"<<endl; return ; } } for(int i=1; i<=n; i++) { if(color[i]==0&&!dfs(i,1)) { cout<<"NO"<<endl; return ; } } for(int i=1;i<=n;i++) if(color[i]==-1) { cout<<"NO"<<endl; return ; } cout<<"YES"<<endl; } int main() { ios::sync_with_stdio(false); cin.tie(0); int m,x,y; while(cin>>n>>m>>x>>y) { for(int i=1;i<=n;i++)v[i].clear(); memset(color,-1,sizeof color); while(m--) { int a,b; cin>>a>>b; color[a]=color[b]=0; v[a].push_back(b); v[b].push_back(a); } for(int i=1;i<=x;i++) { int a; cin>>a; color[a]=1; } for(int i=1;i<=y;i++) { int a; cin>>a; color[a]=2; } solve(); } return 0; } /********************* 5 4 1 2 1 3 1 4 3 5 4 5 2 1 3 *********************/
D:给你a,b,看能不能找到x,y使x+y==a,最小公约数(x,y)==b
题解:y=a-x,然后gcd(x,y)==gcd(a,b),看二元一次方程有没有解
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pii pair<int,int> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 using namespace std; const double g=10.0,eps=1e-7; const int N=2000+10,maxn=60000+10,inf=0x3f3f3f3f; map<ll,ll>m; int main() { for(ll i=0;i<=30000;i++)m[i*i]=i; ll a,b; while(~scanf("%lld%lld",&a,&b)) { ll y=-a,z=__gcd(a,b)*b; if(y*y<4*z)puts("No Solution"); else { if(!m[y*y-4*z]&&y*y-4*z!=0)puts("No Solution"); else { ll p1=-y+m[y*y-4*z],p2=-y-m[y*y-4*z]; if(p1%2==0&&p1/2>0&&p2%2==0&&p2/2>0)printf("%lld %lld\n",min(p1/2,p2/2),max(p1/2,p2/2)); else puts("No Solution"); } } } return 0; }
F:给一个数a,找一堆不相同的数相加为a,使他们相乘最大
题解:直觉。。。2+3+。。+一直加到和大于a为止,然后把最后一位变成2+3+4+5+6+10这种形式,然后把10平摊到前面 的数2+4+5+6+7+8,然后前缀和二分,答案用前缀积+逆元求
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pii pair<int,int> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 using namespace std; const double g=10.0,eps=1e-9; const int N=200000+10,maxn=500+10,inf=40000000; ll f[N],ans[N]; ll quick(ll a,ll b) { ll ans=1; while(b) { if(b&1)ans=(ans*a)%mod; a=(a*a)%mod; b/=2; } return ans; } int main() { ans[0]=1; for(ll i=1;i<=100000;i++) { f[i]=i*(i+1)/2-1; ans[i]=ans[i-1]*i%mod; } int t; scanf("%d",&t); while(t--) { ll x; scanf("%lld",&x); if(x<=4)printf("%lld\n",x); else { ll p=lower_bound(f,f+100000,x)-f; if(f[p]==x)printf("%lld\n",ans[p]); else { if(p-x+f[p-1]!=1)printf("%lld\n",ans[p]*quick(p-x+f[p-1],mod-2)%mod); else printf("%lld\n",ans[p+1]*quick(p,mod-2)%mod*quick(2,mod-2)%mod); } } } return 0; }
H:一个袋子里有n个红球,1个黑球,二个人轮流拿(拿到不放回),拿到黑球算赢,问先拿的人能不能赢
题解:找规律,emmm当n为奇数,可以看出概率为1/2,n为偶数时,把取的整个过程看成全排列那么就是(n+1)!,分成黑球在奇数位和在偶数位,在奇数位就是先手取的情况,
那么概率就是n+2/(2*(n+1)),保证大于0.5
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pii pair<int,int> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 using namespace std; const double g=10.0,eps=1e-9; const int N=200000+10,maxn=500+10,inf=40000000; int main() { int k; while(~scanf("%d",&k)) { if(k&1)puts("0"); else puts("1"); } return 0; }
I水题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pii pair<int,int> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 using namespace std; const double g=10.0,eps=1e-9; const int N=200000+10,maxn=500+10,inf=40000000; int main() { int n,d; while(~scanf("%d%d",&n,&d)) { double ans=0; for(int i=0;i<n;i++) { double ang; scanf("%lf",&ang); ans+=sin(ang/180*pi)/2*d*d; } printf("%.3f\n",ans); } return 0; }
J主要是题意难懂= =,给一堆数,把他化成32位的二进制,然后每8个算一个数(字符),求a的个数,模拟即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pii pair<int,int> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 using namespace std; const double g=10.0,eps=1e-9; const int N=200000+10,maxn=500+10,inf=40000000; int main() { int n,d; while(~scanf("%d",&n)) { string a=""; for(int i=0;i<n;i++) { ll x; scanf("%lld",&x); string p=""; for(int j=1;j<=32;j++) { if(x&1)p+='1'; else p+='0'; x/=2; } reverse(p.begin(),p.end()); a+=p; } ll ans=0; for(int i=0;i<a.size();i+=8) { ll p=0; for(int j=7;j>=0;j--)p+=(1<<(7-j))*(int)(a[j+i]-'0'); if((char)p=='a')ans++; } printf("%d\n",ans); } return 0; }