暑假练习记录(一):2014北京区域赛

一,A Curious Matt

水题一道,排序

#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=10005;
struct node{
	double s,t;
}a[maxn];
bool cmp(node a,node b){
	return a.t<b.t;
}
int main(){
	int t;scanf("%d",&t);
	for(int cnt=1;cnt<=t;cnt++){
		int n;scanf("%d",&n);
		for(int i=0;i<n;i++){
			scanf("%lf%lf",&a[i].t,&a[i].s);
		}
		sort(a,a+n,cmp);
		double ans=0;
		for(int i=1;i<n;i++){
			ans=max(ans,abs(a[i].s-a[i-1].s)/(a[i].t-a[i-1].t));
		}
		printf("Case #%d: %.2lf\n",cnt,ans);
	}
	return 0;
}

二,Black And White

dfs暴搜寻找可行解,注意剪枝

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int ans[6][6];
int n,m,k,c[30];
bool flag=0;
void dfs(int x,int y,int res){
	if(res==0) flag=1;
	if(flag) return;
	for(int i=1;i<=k;i++){
		if((res+1)/2<c[i])return ;   //重要剪枝
	}
	for(int i=1;i<=k;i++){
		if(c[i]&&ans[x-1][y]!=i&&ans[x][y-1]!=i){
			int xx,yy;
			ans[x][y]=i;c[i]--;
			if(y+1>m) xx=x+1,yy=1;
			else xx=x,yy=y+1;
			dfs(xx,yy,res-1);
			if(flag)return ; 
			ans[x][y]=0;c[i]++;		
		}
	}
}
int main(){
	int t;scanf("%d",&t);
	for(int cnt=1;cnt<=t;cnt++){
		flag=0;
		memset(ans,0,sizeof ans);
		scanf("%d%d%d",&n,&m,&k);
		for(int i=1;i<=k;i++){
			scanf("%d",&c[i]);
		}
		dfs(1,1,n*m);
		printf("Case #%d:\n",cnt);
		if(!flag){
			printf("NO\n");continue;
		}
		printf("YES\n");
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if(j==m)printf("%d\n",ans[i][j]);
				else printf("%d ",ans[i][j]);
			}
		}
	}
}

三,Collision

赛后补题,数论加拓展中国剩余定理,事先各项均乘2,保证无小数

#include <iostream>
using namespace std;
typedef long long ll;
int n,a[3],m[3];
//扩展欧几里得 
ll e_gcd(ll a,ll b,ll &x,ll &y){
	if(b==0){
		x=1;y=0;
		return a;
	}
	ll ans=e_gcd(b,a%b,x,y);
	ll temp=x;
	x=y;
	y=temp-a/b*y;
	return ans;
} 
//扩展中国剩余定理 
ll excrt(){
	ll pa=a[1],pm=m[1],x,y;
	for(int i=2;i<=2;i++){
		ll gcd=e_gcd(pm,m[i],x,y);
		ll c=a[i]-pa;
		if(c%gcd!=0)return -1;
		x=c/gcd*x;
		x=(x%(m[i]/gcd)+m[i]/gcd)%(m[2]/gcd);
	  	pa=x*pm+pa;
	  	pm=pm*m[i]/gcd;
	  	pa=(pa%pm+pm)%pm;
	}
	return pa;
}
int main(){
	int t;scanf("%d",&t);
	for(int cnt=1;cnt<=t;cnt++){
		int x,y;ll t,c,d;
		scanf("%d%d",&x,&y);
		int x1,y1,x2,y2;
		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		m[1]=2*x;a[1]=m[1]-x1-x2;
		m[2]=2*y;a[2]=m[2]-y1-y2;
		printf("Case #%d:\n",cnt);
		if(x1==x2&&y1==y2){
			t=0;
		}else if(x1==x2){
			t=a[2];
		}else if(y1==y2){
			t=a[1];		
		}else {
			t=excrt();
			/*ll gcd=e_gcd(m[1],m[2],c,d);
            if((a[2]-a[1])%gcd==0){
                c=(a[2]-a[1])/gcd*c;
                c=(c%(m[2]/gcd)+m[2]/gcd)%(m[2]/gcd);
                t=a[1]+m[1]*c;
            }*/
		}
		if(t==-1){
			printf("Collision will not happen.\n");continue;
		}
		double xx=(x1*2+t)%(2*m[1]);
		double yy=(y1*2+t)%(2*m[2]);
		if(xx>m[1])xx=m[1]*2-xx;
		if(yy>m[2])yy=m[2]*2-yy;
		printf("%.1lf %.1lf\n",xx/2.0,yy/2.0);
	}
	return 0;
}

四,Dire Wolf

 区间dp,注意边界就是了

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
ll dp[205][205];
int a[300],b[300];
int main(){
	int t;scanf("%d",&t);
	for(int cnt=1;cnt<=t;cnt++){
		int n;scanf("%d",&n);
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
		}
		for(int i=1;i<=n;i++){
			scanf("%d",&b[i]);
		}
		b[0]=b[n+1]=0;
		for(int i=1;i<=n;i++){
			dp[i][i]=a[i]+b[i-1]+b[i+1];
		}
		for(int l=1;l<n;l++){
			for(int i=1;i<n;i++){
				int j=i+l;
				if(j>n)break;
				dp[i][j]=min(a[i]+dp[i+1][j],a[j]+dp[i][j-1]);
				for(int k=i+1;k<j;k++){
					dp[i][j]=min(dp[i][j],dp[i][k-1]+a[k]+dp[k+1][j]);
				}
				dp[i][j]+=b[i-1]+b[j+1]; 
			}
		}
		printf("Case #%d: %lld\n",cnt,dp[1][n]);
	}
	return 0;
}

五,Everlasting L 

等待补题,,,,

六,Fluorescent

赛后补题,概率分析加状压dp,,,

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
const int mod=1e9+7;
ll s[55],d[55][8];
int main(){
	int t;scanf("%d",&t);
	for(int cnt=1;cnt<=t;cnt++){
		int n,m;
		memset(s,0,sizeof s);
		scanf("%d%d",&n,&m);
		for(int i=1;i<=m;i++){
			int num;scanf("%d",&num);
			for(int j=0;j<num;j++){
				int te;scanf("%d",&te);
				s[i]|=(ll)1<<te;
			}
		}
		ll ans=0;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				for(int k=1;k<=n;k++){
					memset(d,0,sizeof d);
					d[0][0]=1;
					for(int x=1;x<=m;x++){
						for(int y=0;y<8;y++){
							int temp=y;
							if(s[x]&(1LL<<i))temp^=1;
							if(s[x]&(1LL<<j))temp^=2;
							if(s[x]&(1LL<<k))temp^=4;
							d[x][y]+=d[x-1][y];
							d[x][temp]+=d[x-1][y];
						}
					}
					ans=(ans+d[m][7])%mod;
				}
			}
		}
		printf("Case #%d: %lld\n",cnt,ans);
	}
	return 0;
}

七,GRE Words Once More! 

等待补题,,,,,

八,Happy Matt Friends

异或和为条件的dp揹包,滚动数组,差点就a过去了,呜呜呜,,,

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
const int maxn=2e6+5;
ll dp[2][2*maxn];
int a[45];
int main()
{
	int t;scanf("%d",&t);
	for(int cnt=1;cnt<=t;cnt++)
	{
		int n,m;scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
		}
		memset(dp,0,sizeof dp);
		dp[0][0]=1;
		int e=0;
		for(int i=1;i<=n;i++){
			e=1-e;
			for(int j=0;j<2e6;j++)
				{dp[e][j]=dp[1-e][j]+dp[1-e][j^a[i]];}
		}
		ll ans=0;
		for(int i=m;i<2e6;i++){
			ans+=dp[e][i];
		}
		printf("Case #%d: %lld\n",cnt,ans);
	}
}

九,Intersection 

两园相交求重叠面积,水题,没板子真麻烦,,,

#include<cstdio>
#include<cmath>
using namespace std;
double q,w,m,n,a,b,c,x,y,z,PI;

double area(double a,double b,double c,double x,double y,double z)
{
    //freopen("in.txt","r",stdin);
    PI=2*asin(1.0);
    double l=sqrt((a-x)*(a-x)+(b-y)*(b-y));//计算圆心距
    if(l>=c+z||!c||!z) x=0; //如果两圆相离、外切或至少一圆半径为0时,那么所求面积为0
    else if(l<=fabs(z-c))   //如果两内切或内含,那么所求面积为小圆面积
    {
        if(z>c)z=c;
        x=z*z*PI;
    }
    //如果两圆相交,面积求解如下
    else
    {
        //由余弦定理求出公共弦在圆o1中对应的圆心角的一半    a^2+b^2-c^2=2*a*b*cos(C)
        b=acos((l*l+c*c-z*z)/(2*l*c));
        //由余弦定理求出公共弦在圆o2中对应的圆心角的一半
        y=acos((l*l+z*z-c*c)/(2*l*z));
        //计算圆o1中扇形面积
        m=b*c*c;
        //计算圆o2中扇形面积
        n=y*z*z;
        //计算圆o1中扇形所对应的三角形面积
        q=c*c*sin(b)*cos(b);
        //计算圆o2中扇形所对应的三角形面积
        w=z*z*sin(y)*cos(y);
        //q+w为图中四边形面积,两扇形面积之和与四边形面积之差即为
        //所求面积。在图2中y为钝角,计算出的面积w为负值,这时q+w
        //表示两三角面积之差,刚好还是四边形面积,因此对于图1和图
        //2不必分情况讨论
        x=m+n-(q+w);
    }
    return x;
}
int main(){
	int t;scanf("%d",&t);
	for(int cnt=1;cnt<=t;cnt++){
		scanf("%lf%lf",&c,&z);
		scanf("%lf%lf",&a,&b);
		scanf("%lf%lf",&x,&y);
		double a1=area(a,b,c,x,y,c);
		double a2=area(a,b,z,x,y,z);
		double a3=area(a,b,c,x,y,z);
		double ans=a1+a2-2*a3;
		printf("Case #%d: %.6lf\n",cnt,ans);
	}
}

十,Just A Mistake 

等待补题,,,,,

十一,K.Bro Sorting

水题,随意写,,,,

#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=1e6+5;
int a[maxn];
int main(){
	int t;scanf("%d",&t);
	for(int cnt=1;cnt<=t;cnt++){
		int n;scanf("%d",&n);
		for(int i=0;i<n;i++){
			int x;scanf("%d",&x);
			a[x]=i;
		}
		int ans=0;
		for(int i=2;i<=n;i++){
			if(a[i]<a[i-1]){
				swap(a[i],a[i-1]);
				ans++;
			}
		}
		printf("Case #%d: %d\n",cnt,ans);
	}
	return 0;
}

睡觉睡觉,,,困死,,,, 

 

点赞