ACM搜索训练题

总体很水,但是小错误犯了不少;

1、读懂题意后再做题。

2、注意数据的边界,n是否为0,如果为0是否符合答案

3、多组数据时,初始化是否正确;

4、有没有特殊样例?比如多位数第一位不能为0,但是单独的0可以进行运算;

https://vjudge.net/contest/334226#problem/A

判断出入栈序列是否匹配;

当所有序列号均检查完并符合后,就可以输出答案了;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 20001;
int n,top;
int h[MAXN],b[MAXN];
void solve()
{
	for(int i = 2;i <= n;i ++) 
		cin>>b[i],h[i] = 0;
	int i = 1,j = 1;
	top = 0;
	while(i <= n)
	{
		while(i != b[j] && i <= n)
			h[++top] = i ++;
		h[++top] = i ++;
		while(h[top] == b[j] && j <= n && top >= 1) j ++,top --;
	}
	if(!top &&  j > n) printf("Yes\n");
	else printf("No\n");
	return;
}

int main()
{
	int flag = 1;
	while(cin>>n)
	{
		if(!n) break;
		while(cin>>b[1])
		{
			if(!b[1]) break;
			solve();
		}
		printf("\n");
	}
	return 0;
} 

https://vjudge.net/contest/334226#problem/D

开始没读懂题,所以一直WA,后来是因为初始化不彻底。

深搜可以改变地图状态,只是要记得回溯。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 30;
int n,m,ans,sx,sy,ex,ey;
int ma[MAXN][MAXN];
int X[] = {0,1,-1,0};
int Y[] = {1,0,0,-1};
 
bool pd(int x,int y)
{
	if(x >= 1 && x <= n && y >= 1 && y <= m && ma[x][y] != 1) 
		return true;
	else 
		return false;
}
 
void dfs(int x,int y,int step)
{
	if(step > 10 || step >= ans) return;
	for(int i = 0;i <= 3;i ++)
	{
		int fx = X[i] + x;
		int fy = Y[i] + y;
		if(pd(fx,fy))
		{
			while(pd(fx,fy))
			{
				if(fx == ex && fy == ey)
				{
					ans = min(ans , step + 1);
					return;
				}
				fx += X[i] , fy += Y[i];
			}
			if(ma[fx][fy] == 1)
			{
				ma[fx][fy] = 0;
		 		dfs(fx - X[i],fy - Y[i],step + 1);
		 		ma[fx][fy] = 1;
			}
		}
	}
return;
}

void solve()
{
	memset(ma,0,sizeof(ma));
	ans = 2147483647;
	for(int i = 1;i <= n;i ++)
		for(int j = 1 ;j <= m;j ++)
		{
			scanf("%d",&ma[i][j]);
			if(ma[i][j] == 2) sx = i,sy = j , ma[i][j] = 0;
			else if(ma[i][j] == 3) ex = i,ey = j;
		}
	dfs(sx,sy,0);
	cout << (ans <=10 ? ans : -1)<<endl; 
	return;
}
 
int main()
{
	while(cin >> m >> n , n && m) solve();
	return 0;
}

 

https://vjudge.net/contest/334226#problem/G

全排列……

注意多位数的第一位不能为0,但是单独的0可以进行运算;

一直WA就是因为没有特判;

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath> 
using namespace std;
int T,n,ans = 214748364;
int a[33],b[33];
bool vis[33];
int min(int x,int y)
{
	return x > y ? y : x;
}
int calc()
{
	int sum1 = 0,sum2 = 0,cnt = 1;
	int v = n % 2 ? n / 2 + 1 : n / 2; 
	if(!a[v + 1] || !a[1]) return ans;
	for(int i = v;i >= 1;i --)
	{
		sum1 += cnt * a[i];
		cnt *= 10;
	}
	cnt = 1;
	for(int i = n;i >= v + 1;i --)
	{
		sum2 += cnt * a[i];
		cnt *= 10;
	}
	return abs(sum1 - sum2);
}
void dfs(int k)
{
	if(k == n + 1)
	{
		ans = min(ans,calc());
		return;
	}
	for(int i = 1;i <= n;i ++)
	{
		if(!vis[i])
		{
			vis[i] = 1,a[k] = b[i];
			dfs(k + 1);
			vis[i] = 0;
		}
	}
	return;
}
void solve()
{
	n = 0;
	ans = 214748364;
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	memset(vis,0,sizeof(vis));
	while(1)
	{
		char c = getchar();
		if(c == ' ') continue;
		else if(c == '\n') break;
		else b[++ n] = (int)(c - '0'); 
	}
	if(n == 2)
	{
		cout << max(b[1],b[2]) - min(b[1],b[2]) << "\n";
		return;
	}
	if(n == 10)
	{
		cout << 247 << "\n";
		return;
	}
	dfs(1);
	if(T)
	cout << ans << "\n";
	else cout << ans;
	return; 
}


int main()
{
	cin >> T;
	getchar();
	while(T --) 
	solve();
	return 0;
} 

https://vjudge.net/contest/334226#problem/H

杨辉三角 + 全排列;

https://vjudge.net/contest/334226#problem/J

已知前序遍历和中序遍历求后序遍历;

看的网上的题解

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char s1[1001],s2[1001];
int len;
void dfs(int sz,char *s1,char *s2)
{
	if(sz <= 0) return;
	int pos = strchr(s2,s1[0])-s2;
	dfs(pos ,s1 + 1 ,s2);
	dfs(sz - pos - 1 ,s1 + pos + 1 ,s2 + pos + 1);
	cout << s1[0];
	return;
}

void solve()
{
	while(~scanf("%s%s",s1,s2))
	{
		len = strlen(s1);
		dfs(len ,s1 ,s2);
		cout << endl;
	}
	return;
}

int main()
{
	solve();
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值