zoukankan      html  css  js  c++  java
  • Codeforces Round #532 (Div. 2)

    终于。。

    A - Roman and Browser

    有很多写法,当然我也知道可以暴力,但是前缀和的写法就很舒服啊。

    #include<bits/stdc++.h>
    using namespace std;
    
    char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin))?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	T f=1;ans=0;
    	char ch=gc();
    	while(!isdigit(ch)) {
    		if(ch==EOF) return EOF;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)==EOF?EOF:read(b);
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)==EOF?EOF:read(c);
    }
    
    typedef long long ll;
    const int Maxn=1100000;
    const int inf=0x3f3f3f3f;
    const ll mod=998244353;
    
    int n,k,a[Maxn],s[Maxn],sum,ans;
    
    int main() {
    	read(n,k);
    	for(int i=1;i<=n;i++)
    		read(a[i]),sum+=a[i];
    	for(int i=1;i<k;i++) s[i]=a[i];
    	for(int i=k;i<=n;i++) s[i]=s[i-k]+a[i];
    	for(int i=n-k+1;i<=n;i++) ans=max(ans,abs(sum-s[i]));
    	printf("%d",ans);
    	return 0;
    }
    

    B - Build a Contest

    根据题意直接模拟即可。

    #include<bits/stdc++.h>
    using namespace std;
    
    char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin))?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	T f=1;ans=0;
    	char ch=gc();
    	while(!isdigit(ch)) {
    		if(ch==EOF) return EOF;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)==EOF?EOF:read(b);
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)==EOF?EOF:read(c);
    }
    
    typedef long long ll;
    const int Maxn=1100000;
    const int inf=0x3f3f3f3f;
    const ll mod=998244353;
    
    int n,m,x,cnt[Maxn];
    
    int main() {
    	read(n,m);
    	int temp=0;
    	for(int i=1;i<=m;i++) {
    		read(x);
    		if(cnt[x]==0)
    			temp++;
    		cnt[x]++;
    		if(temp==n) {
    			putchar('1');
    			for(int i=1;i<=n;i++) {
    				cnt[i]--;
    				if(cnt[i]==0) temp--;
    			}
    		}
    		else putchar('0');
    	}
    	putchar('
    ');
    	return 0;
    }
    

    C - NN and the Optical Illusion

    如上图,长度为2r的边就是正n边形的边,那么( heta = frac{2pi}{n})

    那么由余弦定理知,(c^2=a^2+b^2-2abcos C),那么这里的(a=b=R+r,c=2r,C= heta),化一下式子就出来了。

    #include<bits/stdc++.h>
    using namespace std;
    
    char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin))?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	T f=1;ans=0;
    	char ch=gc();
    	while(!isdigit(ch)) {
    		if(ch==EOF) return EOF;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)==EOF?EOF:read(b);
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)==EOF?EOF:read(c);
    }
    
    typedef long long ll;
    const int Maxn=1100000;
    const int inf=0x3f3f3f3f;
    const ll mod=998244353;
    const double Pi=acos(-1);
    
    int n,R;
    
    int main() {
    	read(n,R);
    	double d=2.0*cos(2.0*Pi/n);
    	double a=2.0+d,b=(4.0-2.0*d)*R,c=(2.0-d)*R*R;
    	printf("%.11lf",(b+sqrt(b*b+4.0*a*c))/(2.0*a));
    	return 0;
    }
    

    D - Dasha and Chess

    首先把king移动到中间,然后看一下现在以king为中心的四个象限中那个里面的车最少,然后往相反的方向移。因为少的那个不会超过四分之一也就是166,那另外的三个象限纵沟至少是500个,而king移动的时候另一个人必须把这500个全部放到相反的那个象限里面,而king只会走499步,那么一定能赢。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cctype>
    #define qmin(x,y) (x=min(x,y))
    #define qmax(x,y) (x=max(x,y))
    using namespace std;
    
    inline char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	ans=0;char ch=gc();T f=1;
    	while(!isdigit(ch)) {
    		if(ch==EOF) return -1;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)!=EOF&&read(b)!=EOF?2:EOF;
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
    }
    
    typedef long long ll;
    const int Maxn=1100;
    const int inf=0x3f3f3f3f;
    const int c=500;
    
    int nx,ny,a[Maxn][Maxn],x[Maxn],y[Maxn];
    
    void get(int X,int Y) {
    	if(nx>X) nx--;
    	else if(nx<X) nx++;
    	if(ny>Y&&!a[nx][ny-1]) ny--;
    	else if(ny<Y&&!a[nx][ny+1]) ny++;
    }
    
    void work(int X,int Y) {
    	while(nx!=X||ny!=Y) {
    		get(X,Y);
    		printf("%d %d
    ",nx,ny);
    		fflush(stdout);
    		int b;
    		read(b);
    		if(b<=-1) exit(0);
    		a[x[b]][y[b]]=0;
    		read(x[b],y[b]);
    		a[x[b]][y[b]]=1;
    	}
    }
    
    signed main() {
    //	freopen("test.in","r",stdin);
    	read(nx,ny);
    	for(int i=1;i<=666;i++) read(x[i],y[i]),a[x[i]][y[i]]=1;
    	work(c,c);
    	int zhy=0;
    	for(int i=1;i<=c;i++) for(int j=1;j<=c;j++) if(a[i][j]) zhy++;
    	if(zhy<=166) work(999,999);zhy=0;
    	for(int i=1;i<=c;i++) for(int j=c;j<=999;j++) if(a[i][j]) zhy++;
    	if(zhy<=166) work(999,1);zhy=0;
    	for(int i=c;i<=999;i++) for(int j=1;j<=c;j++) if(a[i][j]) zhy++;
    	if(zhy<=166) work(1,999);
    	work(1,1);
    	return 0;
    }
    
    
    

    E - Andrew and Taxi

    首先把边按权值从小到大排序,然后二分最后的发生变向的边是哪一个。

    那么这条边后面的边一定都没有变向,如果这里面有环,那么就排除,然后继续二分。

    最后求出来为使得后面没有环,最后的发生变向的边。显然后面的边形成一个DAG,那么求出来DAG上的拓扑序,然后对于所有的边,由拓扑序小的指向拓扑序大的即可。

    #include<bits/stdc++.h>
    using namespace std;
    
    char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin))?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	T f=1;ans=0;
    	char ch=gc();
    	while(!isdigit(ch)) {
    		if(ch==EOF) return EOF;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)==EOF?EOF:read(b);
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)==EOF?EOF:read(c);
    }
    
    typedef long long ll;
    const int Maxn=1100000;
    const int inf=0x3f3f3f3f;
    const ll mod=998244353;
    const double Pi=acos(-1);
    
    int n,m,d[Maxn],first[Maxn],nxt[Maxn],to[Maxn],tot=1,vis[Maxn],bj[Maxn];
    queue<int> q;
    
    inline void add(int u,int v) {
    	to[tot]=v;
    	nxt[tot]=first[u];
    	first[u]=tot++;
    }
    
    int dfs(int root) {
    	vis[root]=1;
    	bj[root]=1;
    	for(int i=first[root];i;i=nxt[i])
    		if(bj[to[i]]) {
    			bj[root]=0;
    			return 1;
    		}
    		else if(dfs(to[i])) {
    			bj[root]=0;
    			return 1;
    		}
    	bj[root]=0;
    	return 0;
    }
    
    struct node {
    	int u,v,w,id;
    }a[Maxn];
    
    int cmp(node a,node b) {
    	return a.w<b.w;
    }
    
    int main() {
    	read(n,m);
    	for(int i=1;i<=m;i++) {
    		read(a[i].u,a[i].v,a[i].w);
    		a[i].id=i;
    	}
    	sort(a+1,a+m+1,cmp);
    	int l=1,r=m,mid=l+r>>1,ans=0;
    	while(l<=r) {
    		memset(first,0,sizeof(first));
    		memset(vis,0,sizeof(vis));
    		tot=1;int flag=0;
    		for(int i=mid;i<=m;i++) add(a[i].u,a[i].v);
    		for(int i=1;i<=n;i++) if(!vis[i]) {
    			if(dfs(i)) {
    				flag=1;
    				break;
    			}
    		}
    		if(flag)
    			l=mid+1;
    		else {
    			r=mid-1;
    			ans=mid;
    		}
    		mid=l+r>>1;
    	}
    	memset(first,0,sizeof(first));tot=1;
    	for(int i=ans;i<=m;i++)
    		add(a[i].u,a[i].v),d[a[i].v]++;
    	for(int i=1;i<=n;i++) if(!d[i]) q.push(i);
    	int cnt=0;
    	while(!q.empty()) {
    		int now=q.front();q.pop();
    		vis[now]=++cnt;
    		for(int i=first[now];i;i=nxt[i]) {
    			d[to[i]]--;
    			if(!d[to[i]]) q.push(to[i]);
    		}
    	}
    	cnt=0;
    	for(int i=1;i<=m;i++)
    		if(vis[a[i].v]<vis[a[i].u]) d[a[i].id]=1,cnt++;
    	if(!ans) ans++;
    	printf("%d %d
    ",a[ans-1].w,cnt);
    	for(int i=1;i<=m;i++) if(d[i]) printf("%d ",i);
    	return 0;
    }
    

    F - Ivan and Burgers

    开始的时候想用ST表套线性基,卡了一会空间之后才发现空间复杂度是假的,于是膜拜了一下别人的神奇写法。

    就是把右端点相同的询问放在一起处理,由于有了位置这个限制,那么我们贪心地一定是优先选靠右的点,未来的用处一定更大,如果你会线性基的话,看一下代码就明白了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cctype>
    #define qmin(x,y) (x=min(x,y))
    #define qmax(x,y) (x=max(x,y))
    using namespace std;
    
    inline char gc() {
    //	static char buf[100000],*p1,*p2;
    //	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    	return getchar();
    }
    
    template<class T>
    int read(T &ans) {
    	ans=0;char ch=gc();T f=1;
    	while(!isdigit(ch)) {
    		if(ch==EOF) return -1;
    		if(ch=='-') f=-1;
    		ch=gc();
    	}
    	while(isdigit(ch))
    		ans=ans*10+ch-'0',ch=gc();
    	ans*=f;return 1;
    }
    
    template<class T1,class T2>
    int read(T1 &a,T2 &b) {
    	return read(a)!=EOF&&read(b)!=EOF?2:EOF;
    }
    
    template<class T1,class T2,class T3>
    int read(T1 &a,T2 &b,T3 &c) {
    	return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
    }
    
    typedef long long ll;
    const int Maxn=500001;
    const int inf=0x3f3f3f3f;
    
    int n,a[Maxn],q,l[Maxn],x,ans[Maxn],p[21],po[21];
    vector<int> v[Maxn];
    
    signed main() {
    //	freopen("test.in","r",stdin);
    	read(n);
    	for(int i=1;i<=n;i++) read(a[i]);
    	read(q);
    	for(int i=1;i<=q;i++) {
    		read(l[i],x);
    		v[x].push_back(i);
    	}
    	for(int i=1;i<=n;i++) {
    		int x=a[i],y=i;
    		for(int j=20;j>=0;j--) if(x&(1<<j)) {
    			if(!p[j]) { p[j]=x; po[j]=y; break; }
    			if(po[j]<y) swap(x,p[j]),swap(y,po[j]);
    			x^=p[j];
    		}
    		for(int j=0;j<v[i].size();j++)
    			for(int k=20;k>=0;k--) if(po[k]>=l[v[i][j]])
    				qmax(ans[v[i][j]],ans[v[i][j]]^p[k]);
    	}
    	for(int i=1;i<=q;i++) printf("%d
    ",ans[i]);
    	return 0;
    }
    
    
    
  • 相关阅读:
    POJ 3278 Catch That Cow (附有Runtime Error和Wrong Answer的常见原因)
    POJ 2251 Dungeon Master (三维BFS)
    HDU 1372 Knight moves
    [Ubuntu] <uptime>命令
    【C】哈夫曼编码
    【C++】开辟数组未初始化问题
    免费下载IEEE论文
    随机换装
    BFS解迷宫问题(Go实现)
    DFS解迷宫问题(Go实现)
  • 原文地址:https://www.cnblogs.com/shanxieng/p/10265164.html
Copyright © 2011-2022 走看看