hdu 4272 LianLianKan
解题思路:
1.贪心(错误):无论取就近的数删除还是最远的数删除,均不对;
相应测试数据: 3 2 4 4 1 3 1 2 1 1
1 4 4 3 1 3 2 2 1 1
2.搜索(可以水过数据,必须处理各个数出现偶数次,否则会超时)
处理1:
map<int>mp; for(int i=1; i<=n; i++) { scanf("%d",&a[i]); mp[a[i]]++; …… } if(n&1) { printf("0\n"); continue; } //加个map判断就是0ms,否则就是TLE map<int,int>::iterator it; for(it=mp.begin(); it!=mp.end(); it++) { if((it->second)%2==1) { t=0; break; } …… }
处理2:
while(~scanf("%d",&n)) { int t=0; for(i=1; i<=n; i++) // 改动了起点 将起点定位11 可防止RE { scanf("%d",&a[i+10]); t=t^a[i+10]; } if(t) // a[n]中有数的个数为奇数的话 直接输出0 { printf("0\n"); continue ; } …… }
#include <iostream> #include <cstdio> #include <cstring> #define maxn 1015 using namespace std; int n,m,ans,flag; int a[maxn]; void dfs(int pos) { //if(flag) return ; /*printf("%#d\n",pos); for(int j=n+10; j>10; j--) if(a[j]!=-1)printf("%d ",a[j]); printf("\n");*/ int i,tmp,tp; if(pos==10) { flag=1;// 如果搜到结果就直接return return ; } if(a[pos]==-1)//前一个被找到 { dfs(pos-1); } else { int j=pos; int p=0; for(i=pos-1; j-i<=5; i--) // 每次只搜5的宽度 { if(a[i]==-1)p++,i++; //printf("%d %d\n",a[j],a[i-p]); if(a[i-p]==a[pos]) { tmp=a[i-p]; tp=a[pos]; a[i-p]=-1; a[pos]=-1; dfs(pos-1); a[i-p]=tmp; a[pos]=tp; } if(flag)break; } } } int main() { int i,j,t; for(i=0; i<=10; i++) { a[i]=-1; } while(~scanf("%d",&n)) { t=0; for(i=1; i<=n; i++) // 改动了起点 将起点定位11 可防止RE { scanf("%d",&a[i+10]); t=t^a[i+10];//||t } if(t) // 如果n为奇数 或者a[n]中有数的个数为奇数的话 直接输出0 { printf("0\n"); continue ; } flag=0; dfs(n+10); printf("%d\n",flag); } return 0; }
对于数据1 2 2 3 3 4 4 1 ,我认为不符合题意输出应为0(提供的代码是此理解)
3。模拟亦可水过
- 12
- 1 2 2 1 3 1 1 1 1 1 1 3
- 第一步消去 1 1得 2 2 3 1 1 1 1 1 1 3
- 第二步消去 2 2得 3 1 1 1 1 1 1 3
- 第三步由于两个3之间差距大于等于6,那么我们先消去1,得 3 1 1 1 1 3
- 第四步 消去3 3得 1 1 1 1
- ......
- 那么从上面这个例子可以看出,并不是要求必须一个一个的消除过去,而是可以选择的。那么这样就可以知道只要相同的水果个数为偶数那么肯定是可以消去的,否则不行。 (题意不是这样的~~o(>_<)o ~~)
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <vector> using namespace std; #define MAXN 1010 #define INF 0xFFFFFFF int n; vector<int>v; void solve() { int flag, i; vector<int>::iterator it1, it2; while (1) { //for(int j=0;j<v.size();j++) //printf("%d ",v[j]); //printf("\n"); 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) { v.erase(it1);/*这里删除了it1后it2会往回移动一个*/ v.erase(it2-1);/*所以由上面的可知这里删除it2-1位置*/ flag = 1 ; break; } } if (flag) break; } if (!flag || !v.size()) break;/*如果flag为0或v为空退出*/ } if (v.size()) printf("0\n"); else printf("1\n"); } int main() { //freopen("input.txt", "r", stdin); int tmp; while (scanf("%d", &n) != EOF) { v.clear(); for (int i = 0; i < n; i++) { scanf("%d", &tmp); v.push_back(tmp);/*全部插入vector*/ } solve(); } return 0; }
4,那么也可这么水
#include<stdio.h> int main() { int n,i,t,x; while(scanf("%d",&n)!=EOF) { t=0; for(i=0;i<n;i++) { scanf("%d",&x); t=t^x; } if(t) printf("0\n"); else printf("1\n"); } return 0; }
无力吐槽啊啊啊啊啊啊啊……
5,dp(正解)
本人不善dp,提供搜索代码: