POJ分类一.基本算法

https://vjudge.net/article/6

1.枚举
POJ-1753
题意:4X4枚正反面的硬币 任意翻 翻成同一面最小步数
翻一枚 上下左右全翻
思路:枚举 第一行 0000~1111 16种翻法 因为下一行总能把上一行翻成同一面 用下一行控制上一行 看最后一行满足不满足条件 更新最小值

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <utility>
#include <map>
#include <vector>
#include <queue>
using namespace std;
const int N=10;
char g[N][N],back[N][N];
void turn(int x,int y)
{
    if(g[x][y]=='b')g[x][y]='w';
    else g[x][y]='b';
    int dx[4]={0,-1,0,1},dy[4]={-1,0,1,0};
    for(int i=0;i<4;i++)
    {
        int nx=dx[i]+x,ny=y+dy[i];
        if(nx>=0&&nx<=3&&ny>=0&&ny<=3)
        {
            if(g[nx][ny]=='b')g[nx][ny]='w';
            else g[nx][ny]='b';
        }
    }
}
int work()
{
    int ans=1e9;
    memcpy(back,g,sizeof g);
    for(int k=0;k<1<<4;k++)//枚举第一行所有可能按的方式 w->b
    {
        int res=0;
        for(int j=0;j<4;j++)
            if(k>>j&1)res++,turn(0,j);
            
        for(int i=0;i<3;i++)
            for(int j=0;j<4;j++)
            if(g[i][j]=='w') turn(i+1,j), res++;
            
          
        bool flag=true;
        for(int j=0;j<4;j++)
        if(g[3][j]=='w')flag=false;
        
        if(flag)ans=min(ans,res);
        memcpy(g,back,sizeof back);
    }
       for(int k=0;k<1<<4;k++)//枚举第一行所有可能按的方式
    {
        int res=0;
        for(int j=0;j<4;j++)
        if(k>>j&1) res++,turn(0,j);
            
        
        for(int i=0;i<3;i++)
            for(int j=0;j<4;j++)
            if(g[i][j]=='b')turn(i+1,j),res++;
            
        bool flag=true;
        for(int j=0;j<4;j++)
        if(g[3][j]=='b')flag=false;
        
        if(flag)ans=min(ans,res);
        memcpy(g,back,sizeof back);
    }
    return ans;
}
void solve()
{
   for(int i=0;i<4;i++)cin>>g[i];
   int t=work();
   if(t==1e9)cout<<"Impossible"<<endl;
   else cout<<t<<endl;
}
int main()
{
    int tests=1;
    while(tests--)
    {
        solve();
    }
     return 0;
}

POJ-2965
题意:与上题区别是 动一个 同行同列全翻
思路:枚举每一行16种选择 使用位运算 0表示开 1表示关 如果当前状态是0则表示冰箱门全开了

#include <algorithm>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <utility>
#include <vector>
#include <cmath>
#define fi first
#define sc second
using namespace std;
typedef long long LL;
typedef pair<int,int>PII;
const int N=10;
int a[N],state=0,res=0,minn=1e9;
char g[N][N];
void turn(int x,int y)
{
	for(int i=x*4-1;i>=4*(x-1);i--)state^= 1<<i;
	for(int i=y-1;i<=15;i+=4)state^= 1<<i;
	state^= (1<<(y-1+(x-1)*4));
}
vector <int>temp[N],ans[N];
void dfs(int x)
{
	if(x==5)
	{
		if(state==0)
		{
			if (minn>res)
			{
				minn=res;
				for(int i=1;i<=4;i++)
				{
					ans[i].clear();
					for(int j=0;j<temp[i].size();j++)ans[i].push_back(temp[i][j]);
				}
			}
		}
		return ;
	}
	int backup=res,b1=state;

	for(int i=0;i<1<<4;i++)
	{
		for(int j=0;j<=3;j++)
		{
			if(i>>j&1)
			{
				res++;
				turn (x,j+1);
				temp[x].push_back(j+1);
			}
		}
		dfs(x+1);
		res=backup;
		temp[x].clear();
		state=b1;
	}
}
void solve()
{
	for(int i=0;i<=3;i++)
	{
		scanf("%s",&g[i]);
		for(int j=0;j<=3;j++)if(g[i][j]=='+')state+= (1<<(i*4+j));
	}
	dfs(1);
	printf("%d\n",minn);
	for(int i=1;i<=4;i++)
		for(int j=0;j<ans[i].size();j++)
			printf("%d %d\n",i,ans[i][j]);	
	puts("");
}
int main()
{
	int tests=1;
	//scanf("%d",&tests);
	while(tests--)
	{
		solve();
	}
	return 0;
}

2.贪心
POJ-1328
每个岛的极限位置建雷达站 排序 如果y轴上大于雷达范围 就输出-1

#include <algorithm>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <utility>
#include <vector>
#include <cmath>
#define fi first
#define sc second
using namespace std;
const int N=1e3+10;
typedef long long LL;
typedef pair<double,double>PDD;
int  n,d;
PDD q[N];
int tt=0;
int cmp(PDD A,PDD B)
{
	double r1=A.fi+sqrt(d*d-A.sc*A.sc);
	double r2=B.fi+sqrt(d*d-B.sc*B.sc);
	return r1<r2;
}

void solve()
{
	bool flag=false;int ans=1;
	for(int i=0;i<n;i++)
	{
		double x,y;scanf("%lf %lf",&x,&y);
		q[i]=make_pair(x,y);
		if(y>d)flag=true;
	}
	printf("Case %d: ",++tt);
	if(flag)
	{
		printf("-1\n");return;
	}
	sort(q,q+n,cmp);
	double last=(q[0].fi+sqrt(d*d-q[0].sc*q[0].sc));
	for(int i=1;i<n;i++)
	{
		double x=last-q[i].fi,y=q[i].sc;
		if(x*x+y*y>d*d)
		{
			ans++;
			last=(q[i].fi+sqrt(d*d-q[i].sc*q[i].sc));
		}
	}
	printf("%d\n",ans);
}
int main()
{
	int tests;
	//scanf("%d",&tests);zcin.tie(0);
	//ios::sync_with_stdio(0);cin.tie(0);
	while(scanf("%d%d",&n,&d),n||d)
	//while(tests--)
	{
		solve();
	}

	return 0;
}

POJ-2109
k的n次方等于p 给n,p求k (1<=n<= 200, 1<=p<1e101)
直接输出p的n分之一次方 因为double可以取到1e308

#include <algorithm>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <utility>
#include <vector>
#include <cmath>
#define fi first
#define sc second
using namespace std;
typedef long long LL;
double  n,p;
void solve()
{
	printf("%.0f\n",pow(p,1.0/n));
}
int main()
{
	int tests;
	//scanf("%d",&tests);zcin.tie(0);
	//ios::sync_with_stdio(0);cin.tie(0);
	while(~scanf("%lf%lf",&n,&p))
	//while(tests--)
	{
		solve();
	}
	return 0;
}

POJ-2586
题目说每连续5个月的报表都显示亏损了(共8个 如1到5 8到12) 问整年最大的盈余是多少
思路:比较月盈余s与月亏损d 5个里面选最少个d让连续5月都亏损
d s
4s<d 2 10
3s<2d 4 8
2s<3d 6 6
s<4d 9 3 (补个12)
5d 12 0

#include <algorithm>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <utility>
#include <vector>
#include <cmath>
#define fi first
#define sc second
using namespace std;
typedef long long LL;
LL  s,d;
void solve()
{
	LL delta,beishu=0;
	for(int i=1;i<=5;i++)
	{
		if(s*(5-i)-d*i<0)
		{
			beishu=(5-i);
			break;
		}
	}
	if(beishu>=2)delta=(2+beishu*2)*s-(12-2-beishu*2)*d;
	else if(beishu==1)delta=3*s-9*d;
	else delta=-12*d;
	if(delta<=0)puts("Deficit");
	else printf("%lld\n",delta);
}
int main()
{
	int tests;
	//scanf("%d",&tests);zcin.tie(0);
	//ios::sync_with_stdio(0);cin.tie(0);
	while(~scanf("%lld%lld",&s,&d))
	//while(tests--)
	{
		solve();
	}

	return 0;
}

5.构造法
POJ-3295

#include <algorithm>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <utility>
#include <vector>
#include <cmath>
#define fi first
#define sc second
using namespace std;
typedef long long LL;
typedef pair<int,int>PII;
const int N=110;
char str[N];
int p,q,r,s,t;
int a[N],hh=0;
void check()
{

	int len=strlen(str);
	for(int i=len-1;i>=0;i--)
	{
		if(str[i]=='p')a[++hh]=p;
		if(str[i]=='q')a[++hh]=q;
		if(str[i]=='r')a[++hh]=r;
		if(str[i]=='s')a[++hh]=s;
		if(str[i]=='t')a[++hh]=t;
		if(str[i]=='K')
		{
			int t1=a[hh],t2=a[--hh];
			a[hh]=t1&&t2;
		}
		if(str[i]=='A')
		{
			int t1=a[hh],t2=a[--hh];
			a[hh]=t1||t2;
		}
		if(str[i]=='N')
		{
			a[hh]=!a[hh];
		}
		if(str[i]=='C')
		{
			int t1=a[hh],t2=a[--hh];
			if(t1==0&&t2==1)a[hh]=0;
			else a[hh]=1;
		}
		if(str[i]=='E')
		{
			int t1=a[hh],t2=a[--hh];
			a[hh]=(t1==t2);
		}
	}
}
void solve()
{
	for( p=0;p<2;p++)
	{
		for( q=0;q<2;q++)
		{
			for( r=0;r<2;r++)
			{
				for( s=0;s<2;s++)
				{
					for( t=0;t<2;t++)
					{
						hh=0;
						check();
						if(a[1]==0)
						{
							puts("not");
							return ;
						}
					}
				}
			}
		}
	}
	puts("tautology");
}
int main()
{
	int tests=1;
	//scanf("%d",&tests);
	while(~scanf("%s",&str),str[0]!='0')
	{
		solve();
	}

	return 0;
}

6.模拟法
POJ-1068
数据量小 直接还原出原字符串 再按照题意模拟

#include <algorithm>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <utility>
#include <vector>
#include <cmath>
#define fi first
#define sc second
using namespace std;
typedef long long LL;
const int N=2e5+10;
int a[N];
bool flag[N];
void solve()
{
	vector <char>v;
	int n;scanf("%d",&n);
	int last=0;
	for(int i=1;i<=n;i++)
	{
		int x;scanf("%d",&x);
		if(x>last)
		{
			for(int j=1;j<=x-last;j++)v.push_back('(');
			last=x;
		}
		v.push_back(')');
	}
	memset(flag,0,sizeof flag);
	for(int i=0;i<v.size();i++)
	{
		if(v[i]==')')
		{
			int num=0;
			for(int j=i;j>=0;j--)
			{
				if(v[j]=='(')
				{
					num++;
				}
				if(flag[j]==false&&v[j]=='(')
				{
					flag[j]=true;
					printf("%d ",num);
					break;
				}
			}
		}
	}
	puts("");


}
int main()
{
	int tests;
	scanf("%d",&tests);
	//ios::sync_with_stdio(0);cin.tie(0);
	//while(~scanf("%lld%lld",&s,&d))
	while(tests--)
	{
		solve();
	}

	return 0;
}

POJ-2632
模拟
注意负数的模运算 要加mod

#include <algorithm>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <utility>
#include <vector>
#include <cmath>
#define fi first
#define sc second
using namespace std;
typedef long long LL;
typedef pair<int,int>PII;
const int N=110;
PII q[N];
int n,m,a,b;int ne[N];
int dx[4]={-1,0,1,0},dy[4]={0,-1,0,1};// w s e n
void solve()
{
	scanf("%d %d",&a,&b);
	scanf("%d %d",&n,&m);//b hang  a lie
	for(int i=1;i<=n;i++)
	{
		int x,y;char c;
		scanf("%d %d %c",&x,&y,&c);
		q[i]=make_pair(x,y);
		if(c=='W')ne[i]=0;
		if(c=='S')ne[i]=1;
		if(c=='E')ne[i]=2;
		if(c=='N')ne[i]=3;
	}
	int  flag=0,l1,l2;
	while(m--)
	{
		int x;char op ;int t;
		scanf("%d %c %d",&x,&op,&t);
		if(flag)continue;

		if(op=='F')
		{
			int y=ne[x];
			//q[i].fi+=dx[y]*t,q[i].sc+=dy[y]*t;
			for(int i=1;i<=t;i++)
			{
				q[x].fi+=dx[y],q[x].sc+=dy[y];
				for(int j=1;j<=n;j++)
				{
					if(j==x)continue;
					if(q[x].fi==q[j].fi&&q[x].sc==q[j].sc)
					{
						l1=x,l2=j;

						flag=1;break;
					}
				}
				if(q[x].fi>a||q[x].fi<1||q[x].sc>b||q[x].sc<1)
				{
					flag=2;
					l1=x;
					break;
				}
				if(flag)break;
			}
		}
		else if(op=='L')
		{
			ne[x]=(ne[x]+t%4)%4;
		}
		else
		{
			ne[x]=(4+ne[x]-t%4)%4;
		}
	}
	if(flag==1)
	{
		printf("Robot %d crashes into robot %d\n",l1,l2);
	}
	if(flag==2)printf("Robot %d crashes into the wall\n",l1);
	if(!flag)puts("OK");

}
int main()
{
	int tests;
	scanf("%d",&tests);
	while(tests--)
	{
		solve();
	}

	return 0;
}

POJ-1573

#include <algorithm>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <utility>
#include <vector>
#include <cmath>
#define fi first
#define sc second
using namespace std;
typedef long long LL;
typedef pair<int,int>PII;
const int N=20;
int n,m,c,step=0;
char g[N][N];
int flag[N][N];
bool ok=false;
void dfs(int x,int y)
{
	if(ok)return ;
	if(flag[x][y])
	{
		int l2=step-flag[x][y]+1;
		printf("%d step(s) before a loop of %d step(s)\n",flag[x][y]-1,l2);
		ok=true;
	}
	if(x<0||x>=n||y<0||y>=m)
	{
		printf("%d step(s) to exit\n",step);
		ok=true;
	}
	flag[x][y]=++step;
	if(g[x][y]=='E')dfs(x,y+1);
	if(g[x][y]=='W')dfs(x,y-1);
	if(g[x][y]=='N')dfs(x-1,y);
	if(g[x][y]=='S')dfs(x+1,y);

}
void solve()
{
	ok=false;step=0;memset(flag,0,sizeof flag);
	for(int i=0;i<n;i++)
	{
		scanf("%s",&g[i]);
		//printf("%s\n",g[i]);
	}
	dfs(0,c-1);
}
int main()
{
	int tests;
	//scanf("%d",&tests);
	while(scanf("%d%d%d",&n,&m,&c),n&&m&&c)
	{
		solve();
	}
	return 0;
}
posted @ 2021-08-17 15:02  liv_vil  阅读(336)  评论(0)    收藏  举报