ACM/ICPC乌鲁木齐2017解题报告

BEH三题是我写的，其余题目鸣谢二位大腿。

A:Banana

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int T,n,m,a[100][100],b[100][100],ans[100][100];
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=50;i++)
for(int j=1;j<=50;j++)
a[i][j]=0,b[i][j]=0,ans[i][j]=0;
for(int i=1,x,y;i<=n;i++)
scanf("%d%d",&x,&y),a[x][y]=1;
for(int i=1,x,y;i<=m;i++)
scanf("%d%d",&x,&y),b[x][y]=1;
for(int i=1;i<=50;i++)
for(int j=1;j<=50;j++)
for(int k=1;k<=50;k++)
if(a[i][k]&&b[k][j]) ans[i][j]=1;
for(int i=1;i<=50;i++)
for(int j=1;j<=50;j++)
if(ans[i][j]) printf("%d %d\n",i,j);
puts("");
}
return 0;
}


B：Out-out control cars

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const double eps=1e-10;
bool solve_mat(double a00,double a01,double a10,double a11,double b0,double b1,double &x0,double &x1){
double det=a00*a11-a01*a10;
if(fabs(det)<eps) return false;
x0=(+a11*b0-a01*b1)/det;
x1=(-a10*b0+a00*b1)/det;
return true;
}
class Point{
public:
double x,y;
Point(){}
Point(double _x,double _y):x(_x),y(_y){}
Point operator + (const Point &b){return Point(x+b.x,y+b.y);}
Point operator - (const Point &b){return Point(x-b.x,y-b.y);}
Point operator * (double b){return Point(x*b,y*b);}
};
bool solve_prm(Point p0,Point d0,Point p1,Point d1,double &t0,double &t1){
//p0+d0*t0 = p1+d1*t1
double a00=d0.x,a01=-d1.x;
double a10=d0.y,a11=-d1.y;
double b0=p1.x-p0.x;
double b1=p1.y-p0.y;
return solve_mat(a00,a01,a10,a11,b0,b1,t0,t1);
}
bool hit(Point p,Point d,Point a,Point b){
//if ray p+dt hits [a,b]
double t0,t1;
if(!solve_prm(p,d,a,b-a,t0,t1)) return false;
if(t0<0) return false;
if(t1<0||t1>1) return false;
return true;
}
bool work(void){
Point B[3],Bd;
for(int i=0;i<3;i++) scanf("%lf%lf",&B[i].x,&B[i].y);scanf("%lf%lf",&Bd.x,&Bd.y);
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
Point p=A[i];
Point a=B[j],b=B[(j+1)%3];
if(hit(p,d,a,b)) return true;
p=B[i];
a=A[j],b=A[(j+1)%3];
if(hit(p,d,a,b)) return true;
}
}
return false;
}
int main(){
int T;scanf("%d",&T);
for(int tot=1;tot<=T;tot++){
printf("Case #%d: ",tot);
if(work()) printf("YES\n");
else printf("NO\n");
}
return 0;
}


C：Coconut

#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define mod 1000000007
#define ll long long
using namespace std;
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int T;
int n, b;
int c[1005], d[1005];
int main()
{
while(T--)
{
for(int i = 1; i <= n; i++)
for(int i = 1; i < n; i++)
int tot = 0;
bool flag = 1;
for(int i = 1; i < n; i++)
{
tot += c[i] - d[i] * b;
if(tot < 0)
{
puts("No");
flag = 0;
break;
}
}
if(flag)puts("Yes");
}
return 0;
}

D：Hack Portals

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
using namespace std;
const int MAXN=1010;
int T,n,L,K,gol[MAXN],x[MAXN],y[MAXN];
int q[MAXN],l,r;
bool used[MAXN];
bool cmp(int i,int j)
{
return x[i]<x[j];
}
int main()
{
scanf("%d",&T);
for(int cas=1;cas<=T;cas++)
{
printf("Case #%d: ",cas);
scanf("%d%d%d",&n,&L,&K);
for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
for(int i=1;i<=n;i++) q[i]=i;
sort(q+1,q+n+1,cmp);
int ans=1000000000;
for(int t=0;t<=32768;t++)
{
l=1,r=n;
bool ok=true;
int nowx=0,nowy=t;
while(true)
{
if(nowy+x[q[r]]-nowx<y[q[r]]) {ok=false;break;}
nowy+=x[q[r]]-nowx,nowx=x[q[r]];
while(l<=r&&y[q[l]]-x[q[l]]<=nowy-nowx) l++;
if(l>r) break;
if(nowy+nowx-x[q[l]]<y[q[l]]) {ok=false;break;}
nowy+=nowx-x[q[l]],nowx=x[q[l]];
while(r>=l&&x[q[r]]+y[q[r]]<=nowx+nowy) r--;
if(l>r) break;
}
if(ok) ans=min(ans,nowy+abs(nowx-K));
}
printf("%d\n",ans);
}
return 0;
}


E：Half-consecutive Numbers

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<set>
using namespace std;
typedef long long LL;
bool test(LL x){
LL r=sqrt(x+0.5);
return r*r==x;
}
bool check(LL n,LL k){
LL m=n*n+k;
return test(m/2);
}
LL lis[100]={0LL,1LL,8LL,49LL,288LL,1681LL,9800LL,57121LL,332928LL,1940449LL,11309768LL,65918161LL,384199200LL,2239277041LL,13051463048LL,76069501249LL,443365544448LL,2584123765441LL,15061377048200LL,87784138523761LL,511643454094368LL,2982076586042449LL,17380816062160328LL,};
int main(){
/*freopen("ilis.out","w",stdout);
LL mx=1e16;
cout<<check(3,-1)<<endl;
for(LL i=1;;i+=2){
if(check(i,-1)){
cout<<(i*i-1)<<"LL,";
if(i*i-1>=mx) break;
}
if(check(i,1)){
cout<<i*i<<"LL,";
if(i*i>=mx) break;
}
}*/
int T;scanf("%d",&T);
for(int tot=1;tot<=T;tot++){
LL n;scanf("%lld",&n);
int i;for(i=0;lis[i]<n;i++);
printf("Case #%d: %lld\n",tot,lis[i]);
}
return 0;
}


F：Islands

#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<deque>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define eps 1e-12
#define mp(a, b) make_pair(a, b)
#define ll long long
#define inf 9000000000000000000LL
#define mod 1000000007
#define pa pair<int,int>
using namespace std;
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int T, n, m;
int ind, scc, top;
int in[10005], out[10005];
int low[10005], dfn[10005], q[10005], bl[10005];
bool inq[10005];
vector<int>e[10005];
void tarjan(int x)
{
low[x] = dfn[x] = ++ind;
q[++top]=x; inq[x]=1;
for(int i = 0; i < e[x].size(); i++)
if(!dfn[e[x][i]])
{
tarjan(e[x][i]);
low[x] = min(low[x], low[e[x][i]]);
}
else if(inq[e[x][i]])
low[x] = min(low[x], dfn[e[x][i]]);
if(low[x] == dfn[x])
{
int now = 0; scc++;
while(x != now)
{
now = q[top]; top--;
bl[now] = scc;
inq[now] = 0;
}
}
}
int main()
{
while(T--)
{
scc = ind = 0;
memset(dfn, 0, sizeof(dfn));
memset(low, 0, sizeof(low));
memset(out, 0, sizeof(out));
memset(in, 0, sizeof(in));
memset(bl, 0, sizeof(bl));
for(int i = 1; i <= 10000; i++)
e[i].clear();
for(int i = 1; i <= m; i++)
{
e[u].push_back(v);
}
for(int i = 1; i <= n; i++)
if(!dfn[i])tarjan(i);
for(int i = 1; i <= n; i++)
for(int j = 0; j < e[i].size(); j++)
if(bl[i] != bl[e[i][j]])
in[bl[e[i][j]]]++, out[bl[i]]++;
int t1 = 0, t2 = 0;
for(int i = 1; i <= scc; i++)
{
if(!in[i])t1++;
if(!out[i])t2++;
}
if(scc == 1)puts("0");
else printf("%d\n", max(t1, t2));
}
return 0;
}

G：Query on String

#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<deque>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define eps 1e-12
#define mp(a, b) make_pair(a, b)
#define ll long long
#define inf 9000000000000000000LL
#define mod 1000000007
#define pa pair<int,int>
using namespace std;
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int q, n, m, Tes;
int t[100005];
{
x++;
if(val == 0)return;
for(int i = x; i <= n; i += i & -i)
t[i] += val;
}
int query(int x)
{
x++;
int ans = 0;
for(int i = x; i; i -= i & -i)
ans += t[i];
return ans;
}
string S, T;
bool check(int x)
{
if(x + m - 1 > n - 1)return 0;
for(int i = 0; i < m; i++)
if(S[x + i] != T[i])return 0;
return 1;
}
int main()
{
while(Tes--)
{
memset(t, 0, sizeof(t));
cin >> S; n = S.length();
cin >> T; m = T.length();
for(int i = 0; i < n; i++)
char ch[2];
while(q--)
{
scanf("%s", ch);
if(ch[0] == 'Q')
{
r = r - m + 1;
if(l > r)
{
puts("0");
}
else
{
int ans = query(r) - query(l - 1);
printf("%d\n", ans);
}
}
else
{
int pos = read() - 1;
scanf("%s", ch);
for(int i = max(0, pos - m + 1); i <= pos; i++)
S[pos] = ch[0];
for(int i = max(0, pos - m + 1); i <= pos; i++)
}
}
puts("");
}
return 0;
}

H:Skiing

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int INF=0x7fffffff/2;
const int SIZEN=10010;
int N,M;
vector<pair<int,int> > c[SIZEN];
void SPFA(vector<pair<int,int> > c[SIZEN],int N,int S,int f[SIZEN]){//图中顶点0~N-1,邻接表为c,以S出发,结果存于f
queue<int> Q;
bool inq[SIZEN]={0};
for(int i=0;i<=N+1;i++) f[i]=-INF;
f[S]=0,inq[S]=true,Q.push(S);
while(!Q.empty()){
int x=Q.front();Q.pop();inq[x]=false;
for(int i=0;i<c[x].size();i++){
int u=c[x][i].first;
if(f[x]+c[x][i].second>f[u]){
f[u]=f[x]+c[x][i].second;
if(!inq[u]){
inq[u]=true;
Q.push(u);
}
}
}
}
}
int f[SIZEN];
void work(void){
SPFA(c,N,0,f);
printf("%d\n",f[N+1]);
}
scanf("%d%d",&N,&M);
int a,b,w;
for(int i=0;i<=N+1;i++) c[i].clear();
for(int i=1;i<=M;i++){
scanf("%d%d%d",&a,&b,&w);
c[a].push_back(make_pair(b,w));
}
for(int i=1;i<=N;i++){
c[0].push_back(make_pair(i,0));
c[i].push_back(make_pair(N+1,0));
}
}
int main(){
int T;scanf("%d",&T);
while(T--){
work();
}
return 0;
}


I：Colored Graph

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int T,n;
int d[510][510],a[510];
int gcd(int a,int b)
{
if(b==0) return a;
return gcd(b,a%b);
}
void print()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
printf("%d",d[i][j]);
if(j!=n) putchar(' ');
else printf("\n");
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
if(n%2==0)
{
for(int i=1;i<=n/2;i++)
for(int j=1;j<=n/2;j++)
if(i!=j) d[i][j]=2;
for(int i=n/2+1;i<=n;i++)
for(int j=n/2+1;j<=n;j++)
if(i!=j) d[i][j]=2;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j&&d[i][j]==0) d[i][j]=1;
}
else if(n%4==1)
{
int total=0;
for(int i=1;i<n;i++)
{
int xx=gcd(i,n);
total++;
for(int st=1;st<=xx;st++)
{
int now=st;
for(int j=1;j<=n/xx;j++)
{
int p=(now+i)%n;
if(p==0) p=n;
d[now][p]=d[p][now]=1;
now=p;
}
}
if(total==(n-1)/4) break;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j&&d[i][j]==0) d[i][j]=2;
}
else
{
int m=n-2;
int total=0;
for(int i=1;i<m;i++)
{
int xx=gcd(i,m);
total++;
for(int st=1;st<=xx;st++)
{
int now=st;
for(int j=1;j<=m;j++)
{
int p=(now+i)%m;
if(p==0) p=m;
d[now][p]=d[p][now]=1;
now=p;
}
}
if(total==(m-1)/4) break;
}
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
if(i!=j&&d[i][j]==0) d[i][j]=2;
for(int i=1;i<=m/2;i++) d[m+1][i]=1,d[i][m+1]=1;
for(int i=m/2+1;i<=m;i++) d[m+1][i]=2,d[i][m+1]=2;
for(int i=1;i<=m/2+1;i++) d[m+2][i]=2,d[i][m+2]=2;
for(int i=m/2+2;i<=m;i++) d[m+2][i]=1,d[i][m+2]=1;
d[m+1][m+2]=d[m+2][m+1]=1;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(d[i][j]==1) a[i]++;
int ans=n*(n-1)*(n-2)/6;
int sum=0;
for(int i=1;i<=n;i++) sum+=a[i]*(n-1-a[i]);
ans-=sum/2;
printf("%d\n",ans);
print();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
d[i][j]=0;
for(int i=1;i<=n;i++) a[i]=0;
}
return 0;
}


J：Our Journey of Dalian Ends

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<map>
#define next next2
using namespace std;
const int INF=1000000000;
int TT,m,tot;
char str1[100010],str2[100010];
map<string,int> M;
int getid(char s[])
{
string str=string(s);
if(M.find(str)==M.end())
{
M[str]=++tot;
}
else return M[str];
}
struct Edge
{
int x,y,w;
Edge(){}
Edge(int x,int y,int w):x(x),y(y),w(w){}
}E[100010];
const int MAXN=100010;
const int MAXM=200010;
int S,T;
int w[MAXM],c[MAXM],cost,flow,dis[MAXN];
int q[MAXN],l,r;
bool used[MAXN];
inline void adde(int f,int t,int ww,int cc)
{
}
bool SPFA()
{
for(int i=1;i<=T;i++) dis[i]=INF,from[i]=0;
dis[S]=0,used[S]=true,q[l=0]=S,r=1;
while(l!=r)
{
int x=q[l++];if(l==T) l=0;
used[x]=false;
if(w[i]>0&&dis[to[i]]>dis[x]+c[i])
{
dis[to[i]]=dis[x]+c[i];
from[to[i]]=i;
if(!used[to[i]])
{
q[r++]=to[i];
if(r==T) r=0;
used[to[i]]=true;
}
}
}
return dis[T]!=INF;
}
void DFS()
{
int x=INF;
for(int i=from[T];i;i=from[fr[i]])
x=min(x,w[i]);
flow+=x;
for(int i=from[T];i;i=from[fr[i]])
w[i]-=x,w[i^1]+=x,cost+=c[i]*x;
}
void MCMF()
{
while(SPFA())
DFS();
}
int main()
{
scanf("%d",&TT);
while(TT--)
{
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int www;
scanf("%s%s%d",str1,str2,&www);
int x=getid(str1),y=getid(str2);
E[i]=Edge(x,y,www);
}
int dalian=getid("Dalian");
int xian=getid("Xian");
int shanghai=getid("Shanghai");
S=2*tot+1,T=2*tot+2;
MCMF();
if(flow!=2) puts("-1");
else printf("%d\n",cost);
M.clear();