题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4272
解题思路:
题目大意:
给你一个栈,每次只能出栈顶和离栈顶五步以内(含五步)的元素,要求这个元素必须和栈顶相同。可以使栈成为空栈,就输出1,否则输出0.
算法思想:
这道题的数据很水,所以有些错误的思想也能过。。。
一般水过得,过不了这组数据:
12
1 3 3 5 5 4 4 1 2 6 6 2
在此只给出正确的算法思想:
题目说:for each top element, it can just link with the same-value element whose distance is less than 6 with it. 你可以从栈顶开始消,最大距离要小于6。(一般错误的代码都不能过这句话。。。)
The next line contains N integer ai indicating the elements from bottom to top.而且题目给出的数据是从栈尾开始给的。。。
直接暴力模拟即可。。。
正确AC代码:
AC代码(dfs+map):
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
map<int,int> m;
int a[1010];
int vis[1010];
int dfs(int n){
while(n && vis[n])
n--;
if(n == 0)
return 1;
if(n == 1)
return 0;
int i = 0,j = n-1;
for(;i <= 5;){
if(j <= 0)
return 0;
if(vis[j]){
j--;
continue;
}
if(a[n] == a[j]){
vis[j] = 1;
if(dfs(n-1))
return 1;
vis[j] = 0;
}
i++;
j--;
}
return 0;
}
int main(){
int n;
while(~scanf("%d",&n)){
m.clear();
memset(vis,0,sizeof(vis));
for(int i = 1; i <= n; i++){
scanf("%d",&a[i]);
vis[i] = 0;
m[a[i]]++;
}
if(n&1){
printf("0\n");
continue;
}
//加个map判断就是0ms,否则就是TLE
int flag = 1;
map<int,int>::iterator it;
for(it = m.begin(); it != m.end(); it++){
if((it->second)%2 == 1){
flag = 0;
break;
}
}
if(flag == 0){
printf("0\n");
continue;
}
printf("%d\n",dfs(n));
}
return 0;
}
错误代码(虽然杭电OJ能过,但是只是数据水了。。。):
AC代码(Nim博弈思想):
#include <cstdio>
using namespace std;
int main(){
int n, v, ans, cnt;
while(scanf("%d", &n) != EOF){
ans = cnt = 0;
for(int i = 0; i < n; i++){
scanf("%d", &v);
ans ^= v;
if(v == 0) cnt++;
}
if(cnt%2 == 0 && ans == 0)
printf("1\n");
else
printf("0\n");
}
return 0;
}
AC代码(vector):
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int n;
vector<int> v;
void solve(){
int i,flag;
vector<int>::iterator it1,it2;
while(1){
flag = 0;
if(v.size() <= 1)
break;
it1 = v.begin();
for(; it1 != v.end(); it1++){
for(it2 = it1+1,i = 1; i < 6 && it2 != v.end(); i++,it2++){
if(*it1 == *it2){
flag = 1;
v.erase(it2);
v.erase(it1);//这两个删除位置不能交换。注意删除次序
break;
}
}
if(flag)
break;
}
if(!flag || !v.size())
break;
}
if(v.size())
printf("0\n");
else
printf("1\n");
}
int main(){
while(~scanf("%d",&n)){
v.clear();
int tmp;
for(int i = 0; i < n; i++){
scanf("%d",&tmp);
v.push_back(tmp);
}
reverse(v.begin(),v.end());
//此处可要,可不要,因为你写几组数据,就会发现,倒着过不来,正着也肯定过不去,
solve();
}
return 0;
}