AtCoder Beginner Contest 091
总结:原本升蓝了要打regular...结果报错名了,只能打不计分的了...
A题AC代码:
#include <bits/stdc++.h>
using namespace std;
int n,m,k;
int main(int argc, char const *argv[])
{
cin>>n>>m>>k;
if(n+m<k)cout<<"No"<<endl;
else cout<<"Yes"<<endl;
return 0;
}
B题题解:用map记录一下两人分别拥有的水果数,然后跑一个循环找最大差值即可。
AC代码:
#include <bits/stdc++.h>
using namespace std;
map<string,int> Q;
const int maxn = 107;
int n,m,a[maxn],b[maxn];
int main(int argc, char const *argv[])
{
cin>>n;
int now = 0;
for(int i=1;i<=n;i++)
{
string s;
cin>>s;
if(!Q.count(s))
{
Q[s]=now;
a[now++]=1;
}
else a[Q[s]]++;
}
cin>>m;
for(int i=1;i<=m;i++)
{
string s;
cin>>s;
if(!Q.count(s))
{
Q[s]=now;
b[now++]=1;
}
else b[Q[s]]++;
}
int ans = 0;
for(int i=0;i<now;i++)
{
ans = max(ans,max(0,a[i]-b[i]));
}
cout<<ans<<endl;
return 0;
}
C题题意:给定2*N个坐标,判断当一个点的X,Y都小于另一个点时可以连接,求前N个点最多可以连接多少后N个点。
C题题解:先判断一个点可以连接的所有点,记录一下,然后跑二分图最大匹配就是答案。
AC代码:
#include <bits/stdc++.h>
using namespace std;
struct node
{
int x,y;
}a[122],b[122];
int n,g[122][122];
int linker[122];
bool used[122];
bool dfs(int u)
{
int v;
for(v=1;v<=n;v++)
if(g[u][v]&&!used[v])
{
used[v]=true;
if(linker[v]==-1||dfs(linker[v]))
{
linker[v]=u;
return true;
}
}
return false;
}
int hungary()
{
int res=0;
int u;
memset(linker,-1,sizeof(linker));
for(u=1;u<=n;u++)
{
memset(used,0,sizeof(used));
if(dfs(u)) res++;
}
return res;
}
int main(int argc, char const *argv[])
{
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i].x>>a[i].y;
for(int i=1;i<=n;i++)cin>>b[i].x>>b[i].y;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i].x<=b[j].x&&a[i].y<=b[j].y)g[i][j]=1;
}
}
cout<<hungary()<<endl;
return 0;
}
D题题意:给定两个个数为N的数组,两两相加得N^2个数,然后求这些数的异或值。
D题题解:HDU5270原题,求异或的题大多按位求值,该题难点在于然后判断两个数相加后的每一位是不是1,对于a+b来说很容易可以看出对于第i位,如果a+b∈[2^i,2^(i+1))∪[3*2^i,2^(i+2))时该位为1.那么应该将a,b对2^(i+1)取模,然后判断,如判断第3位,如果第三位是1,只能有两种结果,分别是0100-0111(不进位)与1100-1111(进位),即[2^i,2^(i+1))∪[3*2^i,2^(i+2)
那么就从最高位开始向下找起,每次找相加大于当前位的数的和,然后取模之后找下一位,因为先找高位,再找低位,所以取模不影响后面的结果。
AC代码:
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ll;
const int maxn=(int)2e5+5;
int n;
ll a[maxn],b[maxn],c[maxn];
void merge (ll *p,ll mod) { //在给定的mod下归并排序
int i,j,k,m;
for(i=1;i<=n;i++) {
c[i]=p[i];
if(p[i]>=mod)c[i]=p[i]%mod;
}
c[n+1]=mod<<1;
sort(c+1,c+1+n);
for(int i=1;i<=n;i++)p[i]=c[i];
}
ll bigthan (ll m) { //大于m的数对对数
int i,j=n;ll ans=0;
for (i=1;i<=n;i++) {
while ((a[i]+b[j])>=m&&j>0) j--;
ans+=n-j;
}
return ans;
}
bool get (ll mod) { //考虑mod位是否为1
merge (a,mod<<1);
merge (b,mod<<1);
ll ans = bigthan(mod) + bigthan(3*mod) - bigthan(mod<<1);
if ( ans%2 ) return true;
return false;
}
int main ()
{
int i;
ll mod,ans;
cin>>n;
for(i=1;i<=n;i++) cin>>a[i];
for(i=1;i<=n;i++) cin>>b[i];
sort(a+1,a+n+1);sort(b+1,b+n+1);
ans=0;mod=(ll)1<<28;
while(mod) {
if (get(mod))
ans+=mod;
mod=mod>>1;
}
cout<<ans<<endl;
}