The 2016 ACM-ICPC Asia Dalian Regional Contest---题解
A - Wrestling Match(二分图染色/2-set/dfs瞎搞均可)
题意:
思路:题意真是**了,好不容易才猜对了题意。。是要判M条件是否矛盾。。但是一直读的题意理解的都是不用判,,
知道题意,就简单了,可以用二分图染色,可以2-sat,,那我就比较厉害了,,我啥都没有,一个dfs随便搞搞,记录下颜色,就A了,可怕的是猜题意猜了5个代码才A的,。,,
代码:
#include <bits/stdc++.h>
using namespace std;
struct AA
{
int x,next;
}pos[30005];
int k,N,M,ans,a,b,x,rt,y,ok,f[2005],vis[2005];
void dfs(int p,int fa,int num)
{
if(vis[p]==0) vis[p]=num;
else if(vis[p]!=num) {ans=1;return;}
int v;
for(int i=f[p];i!=-1;i=pos[i].next)
{
v=pos[i].x;
//cout<<p<<" "<<v<<" "<<vis[v]<<" "<<fa<<" "<<num<<endl;
if(vis[v]==0)
dfs(v,p,num==1?2:1);
else if(vis[v]!=(num==1?2:1)) {ans=1;return;}
else continue;
if(ans) return;
}
}
int main()
{
while(~scanf("%d%d%d%d",&N,&M,&x,&y))
{
ans=0;
for(int i=0;i<=N;i++)
vis[i]=0,f[i]=-1;
k=0;
for(int i=1;i<=M;i++)
{
scanf("%d%d",&a,&b);
pos[++k].x=b;
pos[k].next=f[a];
f[a]=k;
pos[++k].x=a;
pos[k].next=f[b];
f[b]=k;
}
for(int i=1;i<=x;i++)
{
scanf("%d",&rt);
dfs(rt,-1,1);
}
for(int i=1;i<=y;i++)
{
scanf("%d",&rt);
dfs(rt,-1,2);
}
for(int i=1;i<=N;i++)
{
if(vis[i]==0)
{
dfs(i,-1,1);
// break;
}
}
for(int i=1;i<=N;i++)
{
if(vis[i]!=0) continue;
ans=1;
break;
}
if(ans==1)
{
printf("NO\n");
}
else printf("YES\n");
}
}
D - A Simple Math Problem(数学推公式/用素数枚举x,y均可)
题意:
思路:数学的题,太坑了!!输出的x,y要符合x<=y!!!但是题意一点没提!!!因为这WA了一个半小时多!!
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
bool flag;
ll a,b,len,ansx,ansy;
ll p[105],num[105];
void init(ll n)
{
len=0;
for(ll i=2;i*i<=n;i++)
{
if(n%i==0)
{
p[++len]=i;
num[len]=0;
}
while(n%i==0)
{
num[len]++;
n=n/i;
}
}
if(n>1)
{
p[++len]=n;num[len]=1;
}
}
ll fpow(ll n,ll x)
{
ll ans=1;
for(int i=1;i<=x;i++)
ans=ans*n;
return ans;
}
void dfs(ll step,ll sum1,ll sum2)
{
for(int i=0;i<num[step];i++)
{
if(flag) return;
if(step<len)
{
dfs(step+1,sum1*fpow(p[step],i),sum2*fpow(p[step],num[step]));
}
else
{
ll x=sum1*fpow(p[step],i);
ll y=sum2*fpow(p[step],num[step]);
//cout<<x<<" "<<y<<endl;
if(x+y==a)
{
flag=true;
ansx=x;ansy=y;
return;
}
}
}
for(int i=0;i<=num[step];i++)
{
if(flag) return;
if(step<len)
{
dfs(step+1,sum1*fpow(p[step],num[step]),sum2*fpow(p[step],i));
}
else
{
ll x=sum1*fpow(p[step],num[step]);
ll y=sum2*fpow(p[step],i);
//cout<<x<<" "<<y<<endl;
if(x+y==a)
{
flag=true;
ansx=x;ansy=y;
return;
}
}
}
}
int main()
{
while(scanf("%lld%lld",&a,&b)!=EOF)
{
if(a==1)
{
printf("No Solution\n");
continue;
}
if(b==1)
{
if(a==2)
printf("1 1\n");
else
printf("No Solution\n");
continue;
}
init(b);
/*for(int i=1;i<=len;i++)
{
cout<<p[i]<<" "<<num[i]<<endl;
}*/
flag=false;
dfs(1ll,1ll,1ll);
if(flag)
{
if(ansx>ansy) swap(ansx,ansy);
printf("%lld %lld\n",ansx,ansy);
}
else
printf("No Solution\n");
}
return 0;
}
H - To begin or not to begin(概率知识点,水题)
题意:
思路:k是指黑球数量。。。算是一个比较好猜的题意 了,然后就简单了,概率定理,,每次抽,赢的概率一样,所以只可能有0 1的存在,根据奇偶判判就行,
代码:
#include<bits/stdc++.h>
using namespace std;
int N,a,b,c,l,ans;
int main()
{
while(~scanf("%d",&N))
{
if(N%2==0)
printf("1\n");
else
printf("0\n");
}
return 0;
}
I - Convex(正弦定理)
题意:
思路:
就是正弦定理 ,但是一开始用的余弦定理WA了,,,大概是余弦步骤太多,导致精度不够,,,醉醉的
代码:
#include <bits/stdc++.h>
using namespace std;
const double PI=acos(-1.0);
double area(double a,double b,double c)
{
double p=(a+b+c)/2.0;
return sqrt(p*(p-a)*(p-b)*(p-c));
}
double angle(double x)
{
return (x*PI/180.0);
}
int N,DD;
double aa;
int main()
{
while(cin>>N>>DD)
{
double ans=0,D=1.0*DD;
for(int i=1;i<=N;i++)
{
cin>>aa;
double ta=D*D*sin(angle(aa))/2;
ans+=ta;
}
cout<<fixed<<setprecision(3)<<ans<<endl;
}
return 0;
}
J - Find Small A(水题)
题意:
思路:猜题意啊猜题意,猜对了就A了,每8位一判断,不能随便的8位。。。
#include<bits/stdc++.h>
using namespace std;
int N,a,b,c,l,ans;
string s1,s2;
int AA()
{
for(int i=1;i<=8-(s2.size()%8);i++)
s2+='0';
l=0;
for(int i=0;i<s2.size();i+=8)
{
c=0;
for(int j=0;j<s1.size();j++)
{
if(s1[j]!=s2[i+j])
{
break;
}
c++;
//cout<<i<<" "<<j<<" "<<s1<<" "<<s2<<endl;
}
if(c==8) {l++;}
}
return l;
}
int main()
{
b=97;
while(b)
{
s1+=(b%2)+'0';
b/=2;
}
s1+='0';
while(~scanf("%d",&N))
{
ans=0;
for(int i=1;i<=N;i++)
{
scanf("%d",&a);
s2="";
while(a)
{
s2+=(a%2)+'0';
a/=2;
}
ans+=AA();
}
printf("%d\n",ans);
}
return 0;
}