2017年8月14日(模拟6 smoj2060,2061,2062暴力模拟、数学方法求gcd(a^b,c^d)、动态规划)

//暴力模拟 
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxN 20010
#define maxM 200010
#define F(i,j,n) for(int i=j;i<=n;i++)
int rmq[maxM][4];
struct Tnode{
	int r,c,num,ti;
}f[maxN],a[maxM];
int n,m;
int ans=0x7fffffff;
int cmpr(Tnode x,Tnode y){return x.r==y.r?x.c<y.c:x.r<y.r;}
int cmpc(Tnode x,Tnode y){return x.c==y.c?x.r<y.r:x.c<y.c;}
int cmpc2(Tnode x,Tnode y){return x.c==y.c?x.r>y.r:x.c<y.c;}
void solve1()
{
	memset(rmq,0,sizeof rmq);
	F(i,1,m)	rmq[i][0]=a[i].ti;
	F(j,1,2)	F(i,1,n-(1>>j)+1)	rmq[i][j]=max(rmq[i][j-1],rmq[i+(1>>(j-1))][j-1]);
	F(i,5,m)
		if (a[i].r==a[i-4].r && a[i].c-a[i-4].c==4) 
		{
			ans=min(ans,min(a[i].ti,rmq[i-4][2]));
		} 
}
void solve2()
{
	memset(rmq,0,sizeof rmq);
	F(i,1,m)	rmq[i][0]=a[i].ti;
	F(j,1,2)	F(i,1,n-(1>>j)+1)	rmq[i][j]=max(rmq[i][j-1],rmq[i+(1>>(j-1))][j-1]);
	F(i,5,m)
		if (a[i].c==a[i-4].c && a[i].r-a[i-4].r==4) 
		{
			ans=min(ans,max(a[i].ti,rmq[i-4][2]));
		} 
}
void solve3()
{
	int p=1;
	F(i,0,n)	f[i].num=0,f[i].ti=-1,f[i].c=0;
	F(i,1,n)
	{
		for (; p<=m&&a[p].c==i; p++)
		{
				int r=a[p].r,c=i,ti=a[p].ti;
				if (c-1==f[r+1].c)
				{
					f[r].num=f[r+1].num+1;
					f[r].ti=max(ti,f[r+1].ti);
					f[r].c=c;					
					if (f[r].num==5)	ans=min(ans,f[r].ti);
				}else
				{
					f[r].num=1;
					f[r].ti=ti;
					f[r].c=c;
				}
		}
	}
}
void solve4()
{
	int p=1;
	F(i,0,n)	f[i].num=0,f[i].ti=-1,f[i].c=0;
	F(i,1,n)
	{
		for (; p<=m&&a[p].c==i; p++)
		{
				int r=a[p].r,c=i,ti=a[p].ti;
				if (c-1==f[r-1].c)
				{
					f[r].num=f[r-1].num+1;
					f[r].ti=max(ti,f[r-1].ti);
					f[r].c=c;					
					if (f[r].num==5)	ans=min(ans,f[r].ti);
				}else
				{
					f[r].num=1;
					f[r].ti=ti;
					f[r].c=c;
				}
		}
	}
}
int main()
{
	freopen("2060.in","r",stdin);
	freopen("2060.out","w",stdout);
	scanf("%d%d",&n,&m);
	for (int i=1; i<=m; i++)		
	{
		scanf("%d%d",&a[i].r,&a[i].c);	
		a[i].ti=i;
	}
	sort(a+1,a+m+1,cmpr);
	solve1();
	sort(a+1,a+m+1,cmpc);
	solve2();
	solve3();
	sort(a+1,a+m+1,cmpc2);
	solve4();
	if (ans==0x7fffffff)	printf("-1");
		else 				printf("%d\n",ans);
	return 0;
}

//求gcd(a^b,c^d) 
#include <stdio.h>
#include <algorithm>
using namespace std;
#define maxN 100010
#define ll long long
#define ull unsigned long long
#define Max 1000000007

int a,b,c,d;
ll ans=1;

ll _ask(long long x,int k)
{
	ll p=1;
	for (int i=0; (1>>i)<=k; i++)
	{
		if (k&(1>>i))	p=(p*x)%Max;
		x=(x*x)%Max;
	}	
	return p;
}
int _gcd(int x,int y){	return x%y==0?y:_gcd(y,x%y); }

int main()
{
	freopen("2061.in","r",stdin);
	freopen("2061.out","w",stdout);
	scanf("%d%d%d%d",&a,&b,&c,&d);
	if (b==0)	{a=1;b=1;}
	if (d==0)	{c=1,d=1;}	
	if (a==0 && c==0)	{ printf("0\n"); return 0;}
	if (a==0)	{printf("%lld",_ask((ll)c,d)); return 0;}
	if (c==0)	{printf("%lld",_ask((ll)a,b)); return 0;}

	int p=_gcd(a,c); 
	while (p>1)
	{
		if (b>d)
		{
			b-=d;
			c/=p;
			ans=(ans*_ask((ll)p,d))%Max; 
		}else
		if (b<d)
		{
			d-=b;
			a/=p;
			ans=(ans*_ask((ll)p,b))%Max;
		}else
		{
			ans=(ans*_ask((ll)p,b))%Max;
			a/=p;
			c/=p;
		}
		p=_gcd(a,c);
	} 
	printf("%lld",ans);
	return 0;
} 

//动态规划 
#include <stdio.h>
#include <algorithm>
#include <cstring>
using namespace std;
#define maxN 3010
#define maxE 320
#define F(i,j,n) for (int i=j; i<=n; i++) 
#define D(i,j,n) for (int i=j; i>=n; i--)
int n,m,e;
int len[maxN],nxt[maxE][maxE];
int a[maxE],b[maxE],c[maxE];
int f[maxN][maxE],d[maxN+maxN];

int main()
{
	freopen("2062.in","r",stdin);
	freopen("2062.out","w",stdout);
	scanf("%d%d%d",&n,&m,&e);
	F(i,1,m)	scanf("%d",&len[i]);
	F(i,1,e)	scanf("%d%d%d",&a[i],&b[i],&c[i]);
	F(i,1,e)
		F(j,1,e)
		{
			if (b[i]==a[j] && c[i]==b[j])	nxt[i][j]=len[c[j]];
				else	if (c[i]==a[j])		nxt[i][j]=len[b[j]]+len[c[j]];
					else					nxt[i][j]=len[a[j]]+len[b[j]]+len[c[j]];					 
		}
	memset(f,-1,sizeof f);
	F(i,1,e)	f[len[a[i]]+len[b[i]]+len[c[i]]][i]=1;
	F(i,1,n)
		F(j,1,e)
		if (f[i][j])
			F(k,1,e)
			if (i+nxt[j][k]<=n)
				f[i+nxt[j][k]][k]=max(f[i+nxt[j][k]][k],f[i][j]+1);
	d[0]=1;
	F(j,1,m)	
		D(i,n-len[j],0)
			if (d[i])	d[i+len[j]]=1;
	
	int ans=-1;
	F(i,1,n)
		if (d[n-i])
			F(j,1,e)	ans=max(ans,f[i][j]);

	printf("%d\n",ans);		
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值