2016-2017 ACM-ICPC, Asia Tsukuba Regional Contest

题目链接:http://codeforces.com/gym/101158


A

签到题

#include<bits/stdc++.h>
using namespace std;
int a[200010],b[200010];
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	memset(a,0,sizeof(a));
	for(int i = 1;i <= m;i++)
		scanf("%d",&b[i]);
	for(int i = m;i >= 1;i--)
		if(a[b[i]]==0){
			a[b[i]] = 1;
			printf("%d\n",b[i]);
		}
	for(int i = 1;i <= n;i++)
		if(a[i]==0)
			printf("%d\n",i);
}
B

模拟一下,暴一暴就过了啊?

#include<bits/stdc++.h>
using namespace std;
int sv[12][12];
int Xor(int i,int j)
{
	return sv[i][j];
}
int get(string tmp)
{
	int la=0;
	for(int i=0;i<4;i++)
	{
		int id=tmp[i]-'0';
		la=Xor(la,id);
	}
	return la;
}
int ans=0;
bool judge(int now)
{
	string tmp;
	for(int i=0;i<4;i++)
	{
		tmp+=now%10+'0';
		now/=10;
	}
	reverse(tmp.begin(),tmp.end());
	tmp+=get(tmp)+'0';
	for(int i=0;i<5;i++)
	{
		int id=tmp[i]-'0';
		for(int j=0;j<10;j++)
		{
			string S=tmp;
			if(j==id)
			{
				continue;
			}
			S[i]=(j+'0');
			int la=get(S);
			if(!Xor(la,S[4]-'0'))
				return true;
		}
	}
	for(int i=0;i<4;i++)
	{
		string S=tmp;
		swap(S[i],S[i+1]);
		int la=get(S);
		if(S==tmp)
			continue;
		if(!Xor(la,S[4]-'0'))
			return true;
	}
	return false;
}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	for(int i=0;i<10;i++)
	{
		for(int j=0;j<10;j++)
		{
			scanf("%d",&sv[i][j]);
		}
	}
	//judge(2016);
	for(int i=0;i<10000;i++)
	{
		ans+=judge(i);
	}
	printf("%d\n",ans);
	return 0;
}
C

继续模拟

#include<bits/stdc++.h>
using namespace std;
const int MAXN=2e5+5;
struct node{
	int x,y;
}p[MAXN];
struct edge
{
	int x,ca;
	edge(){}
	edge(int _x,int _ca):x(_x),ca(_ca){}
	bool operator < (const edge &a)const
	{
		return x<a.x;
	}
};
vector<edge> DO[MAXN],UP[MAXN];
int cl[MAXN],cs[MAXN];
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i = 0;i < m;i++)
	{
		scanf("%d%d",&p[i].x,&p[i].y);
		DO[p[i].y].push_back(edge(p[i].x,0));
		UP[p[i].y+1].push_back(edge(p[i].x,0));
	}
	DO[0].push_back(edge(0,0));
	UP[n+1].push_back(edge(0,0));
	for(int i=1;i<=n;i++)
	{
		cs[i]=cl[i]=1;
		DO[i].push_back(edge(0,0));
		UP[i].push_back(edge(0,0));
		sort(DO[i].begin(),DO[i].end());
		sort(UP[i].begin(),UP[i].end());
	}
	int at=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<DO[i].size();j++)
		{
			at=DO[i][j].x;
			vector<edge> :: iterator it=upper_bound(DO[i-1].begin(),DO[i-1].end(),edge(at,0));
			it--;
			DO[i][j].ca=it->ca+1;
			cl[i]=max(DO[i][j].ca,cl[i]);
		}
		at=1e9;
		vector<edge> :: iterator it=upper_bound(DO[i-1].begin(),DO[i-1].end(),edge(at,0));
		it--;
		cl[i]=max(it->ca+1,cl[i]);
	}
	for(int i=n;i>=1;i--)
	{
		for(int j=1;j<UP[i].size();j++)
		{
			at=UP[i][j].x;
			vector<edge> :: iterator it=upper_bound(UP[i+1].begin(),UP[i+1].end(),edge(at,0));
			it--;
			UP[i][j].ca=it->ca+1;
			cs[i]=max(UP[i][j].ca,cs[i]);
		}
		at=1e9;
		vector<edge> :: iterator it=upper_bound(UP[i+1].begin(),UP[i+1].end(),edge(at,0));
		it--;
		cs[i]=max(it->ca+1,cs[i]);
	}
	for(int i=1;i<=n;i++)
	{
		//printf("%d %d ",cl[i],cs[i]);
		printf("%d ",cl[i]+cs[i]-1);
	}
}
D

花式暴力?

#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<vector>

using namespace std;

string a, b;
struct cnt {
	int dt[30];
	void init()
	{
		memset(dt, 0, sizeof(dt));
		return;
	}
	inline bool operator<(const cnt & rig)const
	{
		for (int i = 0; i < 30; i++)
		{
			if (dt[i] != rig.dt[i])
			{
				return dt[i] < rig.dt[i];
			}
		}
		return 0;
	}
};

int check(int x)
{
	cnt tmp;
	tmp.init();
	set<cnt>st;
	for (int i = 0; a[i]; i++)
	{
		tmp.dt[a[i] - 'a']++;
		if (i >= x)
		{
			tmp.dt[a[i - x] - 'a']--;
		}
		if (i >= x - 1)
		{
			st.insert(tmp);
		}
	}
	tmp.init();
	for (int i = 0; b[i]; i++)
	{
		tmp.dt[b[i] - 'a']++;
		if (i >= x)
		{
			tmp.dt[b[i - x] - 'a']--;
		}
		if (i >= x - 1)
		{
			if (st.find(tmp) != st.end())
			{
				return 1;
			}
		}
	}
	return 0;
}

int main()
{
	std::ios::sync_with_stdio(false);
	cin >> a >> b;
	int tar = 0;
	for (int i = a.size(); i > 0; i--)
	{
		if (check(i))
		{
			cout << i << "\n";
			tar = 1;
			break;
		}
	}
	if (!tar)
	{
		cout << "0\n";
	}
	//cin >> a;
	return 0;
}
E

python暴力?

s = raw_input()

ans = {}
op = ['+','-','*','==','(',')','0','1']
ops = ['0','0','0','0','0','0','0','0']
inuse = [0,0,0,0,0,0,0,0]
cnt=0

def check():
    global ops
    global cnt
    str = ''
    be = 0;
    cnks = 0
    dict = {}
    for chr in s:
        if not chr.isalpha():
            if chr=='=':
                str += chr
            str += chr
            continue
        if not dict.has_key(chr):
            if be == 8:
                return;
            dict[chr]=be
            be+=1
        str+= ops[dict[chr]]
    tar = 0
    k= len(str)
    lays = 0
    for i in str:
        if i == '(':
            lays+=1
        if i == ')':
            lays -=1
        if i =='=':
            if lays != 0:
                return

    for i in range(len(str)):
        if str[i]=='(' and i != k-1 and str[i+1]==')' :
            return
        if str[i]=='*' and i != k-1 and str[i+1]=='*':
            return
        if str[i]=='+':
            if i == 0 or (str[i-1]!='0' and str[i-1]!='1' and str[i-1]!=')'):
                return
        if str[i]=='=':
            tar+=1
        if i!=k-1 and str[i]=='0' and (i==0 or (str[i-1] != '0' and str[i-1]!= '1')) and (str[i+1]=='0' or str[i+1]=='1'):
            return

    if tar!= 2:
        return
    
    execs = ''
    tar = 1
    for i in str:
        if (i == '0' or i == '1'):
            if tar==1:
                execs += '0b'
                execs += i
                tar=0
            else:
                execs += i
        else:
            execs += i
            tar=1

    try:
        if eval(execs)==True:
            if not ans.has_key(str):
                ans[str]=1
    except:
        cnt = cnt


def dfs(lay):
    global ops
    global op
    global inuse
    if lay == 8:
        check()
        return;
    else:
        for i in range(8):
            if inuse[i]==0:
                ops[lay]=op[i]
                inuse[i]=1
                dfs(lay+1)
                inuse[i]=0
    return;

dfs(0)
print len(ans)
F

bitset优化暴力

#include<bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
using namespace std;
const int MAXN=1005;
vector<int> sv[MAXN][MAXN];
vector<pair<int,int> > edge[MAXN];
bitset<MAXN> G[MAXN];
map<string,int> Hash;
int tot=0;
bool vis[MAXN];
int getid(string now)
{
	int &id=Hash[now];
	if(id==0)
		id=++tot;
	return id;
}
void dfs(int a,int b)
{
	G[a][b]=1;
	for(auto it:sv[a][b])
	{
		if(vis[it])
			continue;
		vis[it]=true;
		for(auto itt:edge[it])
		{
			int p,q;
			p=itt.xx,q=itt.yy;
			if(!G[p][q])
				dfs(p,q);
		}
	}
	for(int i=1;i<=tot;i++)
	{
		if(G[i][a])
		{
			bitset<MAXN> bs=((~G[i])&G[b]);
			G[i]|=G[b];
			for(int j=1;j<=tot;j++)
			{
				if(bs[j])
				{
					for(auto it:sv[i][j])
					{
						if(vis[it])
							continue;
						vis[it]=true;
						for(auto itt:edge[it])
						{
							int p,q;
							p=itt.xx,q=itt.yy;
							if(!G[p][q])
								dfs(p,q);
						}
					}
				}
			}
		}
	}
}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int n;
	string st,en;
	cin>>st>>en;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int k;
		scanf("%d",&k);
		for(int j=1;j<=k;j++)
		{
			string a,b;
			cin>>a>>b;
			int ida=getid(a),idb=getid(b);
			sv[ida][idb].push_back(i);
			edge[i].push_back(mp(ida,idb));
		}
	}
	int start=getid(st),end=getid(en);
	for(int i=1;i<=tot;i++)
		G[i][i]=1;
	dfs(start,end);
	for(int i=1;i<=tot;i++)
	{
		for(int j=i+1;j<=tot;j++)
		{
			if(G[i][j]&&G[j][i])
			{
				return 0*printf("No\n");
			}
		}
	}
	printf("Yes\n");
	return 0;
}

G

思路很巧妙的数学题。。。(具体看题解),set暴力。。。(从cls那里学到了先进的set用法?)

#include<bits/stdc++.h>
using namespace std;
set<int> sv;
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int n;
	int now=1;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		if(x<now-1||sv.count(0))
			puts("No");
		else if(x==now-1&&sv.size()&&*(--sv.end())>x)
			puts("No");
		else
		{
			while(!sv.insert(x).second)
			{
				sv.erase(x);
				x--;
			}
			while(sv.count(now))
				now++;
			puts("Yes");
		}
	}
	return 0;
}
H

很有意思图论题目,可以转换为一个DAG图套树形DP,膜拜了wode cude dalao的代码才看懂。。。

#include<bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
using namespace std;
const int MAXN=1e5+5;
vector<pair<int,int> > sv[3];
vector<int> e[MAXN],E[MAXN],et[MAXN];
//Q
int fa[MAXN],in[MAXN],dp[MAXN],U[MAXN],D[MAXN],A[MAXN];
void Init(int n)
{
    for(int i=1;i<=n;i++)fa[i]=i;
}
int Find(int x)
{
    return x==fa[x] ? x : fa[x]=Find(fa[x]);
}
bool Union(int x,int y)
{
    x=Find(x),y=Find(y);
    if(x==y)return 0;
    return fa[x]=y,1;
}
struct node
{
	multiset<int> s;
	int get()
	{
		return *s.rbegin();
	}
	node(){}
	node(int val)
	{
		s.insert(val);
	}
	void operator += (const int &a)
	{
		s.insert(a);
	}
	int operator - (const int &a)
	{
		int ret;
		auto it=s.find(a);
		s.erase(it);
		ret=get();
		s.insert(a);
		return ret;
	}
};
node tree[MAXN];
void dfsD(int now,int f)
{
	tree[now]=node(dp[now]);
	for(auto i:e[now])
	{
		if(i==f)
			continue;
		dfsD(i,now);
		tree[now]+=(D[i]+1);
	}
	D[now]=tree[now].get();
}
void dfsU(int now,int f)
{
	if(f)
		tree[now]+=(U[now]+1);
	A[now]=tree[now].get();
	for(auto i:e[now])
	{
		if(i==f)
			continue;
		U[i]=tree[now]-(D[i]+1);
		dfsU(i,now);
	}
}
void dfsT(int now,int f)
{
	dp[now]=A[now];
	for(auto i:et[now])
	{
		dp[i]=max(dp[i],dp[now]+1);
	}
	for(auto i:e[now])
	{
		if(i==f)
			continue;
		dfsT(i,now);
	}
}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int n,m;
	scanf("%d%d",&n,&m);
	Init(n);
	for(int i=1;i<=m;i++)
	{
		int u,v,op;
		scanf("%d%d%d",&u,&v,&op);
		sv[op].push_back({u,v});
		if(op==2)
		{
			if(!Union(u,v))
			{
				return 0*puts("Infinite\n");
			}
			e[u].push_back(v);
			e[v].push_back(u);
		}
	}
	for(auto i:sv[1])
	{
		int u,v;
		u=i.xx,v=i.yy;
		u=Find(u),v=Find(v);
		E[u].push_back(v);
		in[v]++;
	}
	vector<int> Q;
	int tot=0;
	for(int i=1;i<=n;i++)
	{
		if(i==Find(i))
		{
			tot++;
			if(in[i]==0)
				Q.push_back(i);
		}
	}
	for(int i=0;i<Q.size();i++)
	{
		int u=Q[i];
		for(auto v:E[u])
		{
			in[v]--;
			if(!in[v])
			{
				Q.push_back(v);
			}
		}
	}
	if(Q.size()!=tot)
	{
		return 0*printf("Infinite\n");
	}
	for(auto i:sv[1])
	{
		int x,y;
		tie(x,y)=i;
		et[x].push_back(y);
	}
	for(auto i:Q)
	{
		dfsD(i,0);
		dfsU(i,0);
		dfsT(i,0);
	}
	printf("%d\n",*max_element(dp+1,dp+1+n));
	return 0;
}
I

这竟然,是个数学题啊?

#include<bits/stdc++.h>
using namespace std;
int gcd(int a,int b,int &x1,int &y1){
    if (b==0){
        x1=1,y1=0;
        return a;
    }
    int q=gcd(b,a%b,y1,x1);
    y1-=a/b*x1;
    return q;
}

int main(){
	int n;
	int x,y,x1,y1;
	scanf("%d",&n);
	while(n--){
		scanf("%d%d",&x,&y);
		if(x<=50000||y<=50000){
		printf("3\n0 0\n%d %d\n",x,y);
		if(x<y)
			printf("0 1\n");
		else
			printf("1 0\n");}
		else
			{
			int z = gcd(x,y,x1,y1);
			int xx = x/z,yy = y/z;
			int ans = (xx+yy);
			if(ans<=50000){
				printf("4\n0 0\n%d %d\n%d %d\n%d %d\n",x-1,y,xx,yy,x,y-1);
				continue;
				}
			printf("3\n");
			printf("0 0\n");
			printf("%d %d\n",x,y); 
			while(x1>0&&y1>0){
				x1 -= yy;
				y1 -= xx;
			}
			printf("%d %d\n",abs(y1),abs(x1));
		}
	}
}
J

模拟退火暴一暴

#include <iostream>
#include <cstdio>
#include <cmath>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define PI acos(-1.0)
#define EPS 1e-10
#include <ctime>
#include<cstdlib>
using namespace std;

inline int DB(double x) {
    if(x<-EPS) return -1;
    if(x>EPS) return 1;
    return 0;
}


struct point {
    double x,y;

    point() {}
    point(double _x,double _y):x(_x),y(_y) {}

    point operator-(point a) {
        return point(x-a.x,y-a.y);
    }
    point operator+(point a) {
        return point(x+a.x,y+a.y);
    }

    double operator*(point a) {
        return x*a.y-y*a.x;
    }

    point oppose() {
        return point(-x,-y);
    }

    double length() {
        return sqrt(x*x+y*y);
    }

    point adjust(double L) {
        L/=length();
        return point(x*L,y*L);
    }

    point vertical() {
        return point(-y,x);
    }

    double operator^(point a) {
        return x*a.x+y*a.y;
    }
};


struct segment {
    point a,b;

    segment() {}
    segment(point _a,point _b):a(_a),b(_b) {}

    point intersect(segment s) {
        double s1=(s.a-a)*(s.b-a);
        double s2=(s.b-b)*(s.a-b);
        double t=s1+s2;
        s1/=t;
        s2/=t;
        return point(a.x*s2+b.x*s1,a.y*s2+b.y*s1);
    }
    point vertical(point p) {
        point t=(b-a).vertical();
        return intersect(segment(p,p+t));
    }
    int isonsegment(point p) {
        return DB(min(a.x,b.x)-p.x)<=0&&
               DB(max(a.x,b.x)-p.x)>=0&&
               DB(min(a.y,b.y)-p.y)<=0&&
               DB(max(a.y,b.y)-p.y)>=0;
    }
};

struct circle {
    point p;
    double R;
};

circle C;
point p[105];
int n;


double cross_area(point a,point b,circle C) {
    point p=C.p;
    double R=C.R;
    int sgn=DB((b-p)*(a-p));
    double La=(a-p).length(),Lb=(b-p).length();
    int ra=DB(La-R),rb=DB(Lb-R);
    double ang=acos(((b-p)^(a-p))/(La*Lb));
    segment t(a,b);
    point s;
    point h,u,temp;
    double ans,L,d,ang1;

    if(!DB(La)||!DB(Lb)||!sgn) ans=0;
    else if(ra<=0&&rb<=0) ans=fabs((b-p)*(a-p))/2;
    else if(ra>=0&&rb>=0) {
        h=t.vertical(p);
        L=(h-p).length();
        if(!t.isonsegment(h)||DB(L-R)>=0) ans=R*R*(ang/2);
        else {
            ans=R*R*(ang/2);
            ang1=acos(L/R);
            ans-=R*R*ang1;
            ans+=R*sin(ang1)*L;
        }
    } else {
        h=t.vertical(p);
        L=(h-p).length();
        s=b-a;
        d=sqrt(R*R-L*L);
        s=s.adjust(d);
        if(t.isonsegment(h+s)) u=h+s;
        else u=h+s.oppose();
        if(ra==1) temp=a,a=b,b=temp;
        ans=fabs((a-p)*(u-p))/2;
        ang1=acos(((u-p)^(b-p))/((u-p).length()*(b-p).length()));
        ans+=R*R*(ang1/2);
    }
    return ans*sgn;
}

double cal_cross(circle C,point p[],int n) {
    double ans=0;
    int i;
    p[n]=p[0];
    for(i=0; i<n; i++) ans+=cross_area(p[i],p[i+1],C);
    return fabs(ans);
}

double x,y,v,det,t,g,R;
const double pi = acos(-1.0); 
double X,Y;
const double err = 1e-6;
double Rand(double L, double R) {
    return (rand() % 10000) / 10000.0 * (R - L) + L;  
} 
int main() {
    srand(time(0));
	scanf("%d%lf",&n,&R);
	C.R=R;
	for(int i=0; i<n; i++) scanf("%lf%lf",&p[i].x,&p[i].y);
    C.p.x = 0;
    C.p.y = 0;
	double anss = 0;
    for(int i=0;i<n;i++)
        anss = cal_cross(C,p,n);;
    //printf("%lf\n",anss);
	double minx =1e5,miny = 1e5,maxx = 0,maxy = 0;
	minx = 0.0;
	miny = 0.0;
	maxx = 100.0;
	maxy = 100.0;
    point cnt;
    double acost = 0.0;
	for(int ii = 1;ii <= n;ii++){	
		point ans;
		ans.x = p[ii].x;
		ans.y = p[ii].y;
		C.p = ans;
   		double ncost = cal_cross(C,p,n);
    	point tmp;
    	double step = max(maxx-minx,maxy-miny);
    	int flag = -1;
    	for (int i = 0;step > 1e-6; i++) {
        	flag = -1;
        	for (int k = 0; k < 40; k++) {
           		double ang = (rand()%1000+1)/1000.0*10*pi;  
				tmp.x = ans.x + step * cos(ang);
           		tmp.y = ans.y + step * sin(ang);
           		C.p = tmp;
         		if (ncost < cal_cross(C,p,n)) {
               		ncost = cal_cross(C,p,n);
               		flag = 1;
               		ans = tmp;
           		}
       		}
       		if (flag == -1) step *= 0.8;
   		}
   		if(ncost>acost){
   			acost = ncost;
   			cnt = ans;
		}
	}
	//printf("(%lf,%lf).\n", cnt.x, cnt.y);
    printf("%lf\n", acost);
	return 0;
}
K

奇奇怪怪的博弈。。。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cctype>
#include<string>
#include<cmath>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<sstream>

using namespace std;

string data;
long long cnt[50], tmps;
int num[50];
int n;
long long base = (1LL << 40);
long long ans;
map<long long, long long>mp;

int main()
{
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> data;
		num[i] = data.size();
		int tar = 0;
		tmps = base;
		for (int j = 0; data[j]; j++)
		{
			if (tar || (j != 0 && data[j] != data[j - 1]))
			{
				tmps /= 2;
				tar = 1;
			}
			if (data[j] == 'B')
			{
				cnt[i] += tmps;
			}
			else
			{
				cnt[i] -= tmps;
			}
		}
	}

	int siz1 = n / 2;
	int siz2 = n - siz1;
	long long val, cos;

	for (long long i = 0; i < (1 << siz1); i++)
	{
		cos = 0;
		val = 0;
		for (int j = 0; j < siz1; j++)
		{
			if (i&(1LL << j))
			{
				cos += cnt[j];
				val += num[j];
			}
		}
		if (mp.find(cos) != mp.end())
		{
			mp[cos] = max(mp[cos], val);
		}
		else
		{
			mp[cos] = val;
		}
	}

	long long ans = 0;

	for (long long i = 0; i < (1 << siz2); i++)
	{
		cos = 0;
		val = 0;
		for (int j = 0; j < siz2; j++)
		{
			if (i&(1LL << j))
			{
				cos += cnt[j + siz1];
				val += num[j + siz1];
			}
		}
		if (mp.find(-1*cos) != mp.end())
		{
			ans = max(ans, mp[-1 * cos] + val);
		}
	}
	cout << ans << "\n";
	//cin >> n;
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值