csdn英雄会题解之翻纸牌游戏__hdu2209
2014-03-22 15:47
253 查看
题目描述 有一种纸牌游戏,很有意思,给你N张纸牌,一字排开,纸牌有正反两面,开始的纸牌可能是一种乱的状态(有些朝正,有些朝反),现在你需要整理这些纸牌。但是麻烦的是,每当你翻一张纸牌(由正翻到反,或者有反翻到正)时,他左右两张纸牌(最左边和最右边的纸牌,只会影响附近一张)也必须跟着翻动,现在给你一个乱的状态,问你能否把他们整理好,使得每张纸牌都正面朝上,如果可以,最少需要多少次操作。
输入 有多个case,每个case输入一行01符号串(长度不超过20),1表示反面朝上,0表示正面朝上。 输出 对于每组case,如果可以翻,输出最少需要翻动的次数,否则输出NO。
我的做法:
每张扑克牌有主动翻和主动不翻(主动翻两次相等于主动不翻)两种情况,那么总共有2^n方种情况,如果这2^n方中情况中仍不能找到使其都为正面朝上,那么肯定就找不到了,因为再继续找下去,肯定会出现某个主动翻两次,又转换为2^n方内的情况了。采用DFS搜索所有情况:
代码为:
由于depth只会影响到depth-1,depth,depth+1,所以如果depth-1以前有反面向上,那么,最后isOk肯定是false,可以进行减枝,代码修改为:
此方法在hdu提交成功,在hero提交提示代码异常,不知道为什么了,调了半天!
还可以通过depth步为了确保depth-1为正面向上而主动翻动来进行优化。可以参见/article/2664050.html
输入 有多个case,每个case输入一行01符号串(长度不超过20),1表示反面朝上,0表示正面朝上。 输出 对于每组case,如果可以翻,输出最少需要翻动的次数,否则输出NO。
我的做法:
每张扑克牌有主动翻和主动不翻(主动翻两次相等于主动不翻)两种情况,那么总共有2^n方种情况,如果这2^n方中情况中仍不能找到使其都为正面朝上,那么肯定就找不到了,因为再继续找下去,肯定会出现某个主动翻两次,又转换为2^n方内的情况了。采用DFS搜索所有情况:
代码为:
#include<iostream> #include<iterator> #include<string> #include<stdio.h> #include<string.h> const int maxn=20; bool flag[maxn];//是否主动翻动过 int times=INT_MAX; bool isOk(const std::string &str){//所有扑克是否正面向上 if(std::string::npos==str.find_first_of('1')) return true; else return false; } void initFlag(){// for(std::size_t i=0;i<maxn;++i) flag[i]=false; } int countFlag(int endId){//统计主动翻动的次数 int res=0; for(std::size_t i=0;i<endId;++i) if(flag[i]) ++res; return res; } void turn(char&a){//翻动 if('1'==a) a='0'; else a='1'; } //depth >=2 void getMin(std::string& str,int depth){ if(depth==str.size()){ if(isOk(str)){ int res=countFlag(str.size()); if(res<times) times=res; } return ; } getMin(str,depth+1); if(depth>0) turn(str[depth-1]); turn(str[depth]); if(depth+1<str.size()) turn(str[depth+1]); flag[depth]=true; getMin(str,depth+1); //回退,恢复状态 if(depth>0) turn(str[depth-1]); turn(str[depth]); if(depth+1<str.size()) turn(str[depth+1]); flag[depth]=false; } int main(int argc,char** argv){ std::string str; while(std::cin>>str){ times=INT_MAX; initFlag(); getMin(str,0); if(times!=INT_MAX) std::cout<<times<<std::endl; else std::cout<<"NO"<<std::endl; } }
由于depth只会影响到depth-1,depth,depth+1,所以如果depth-1以前有反面向上,那么,最后isOk肯定是false,可以进行减枝,代码修改为:
void getMin(std::string& str,int depth){ if(depth==str.size()){ if(isOk(str)){ int res=countFlag(str.size()); if(res<times) times=res; } return ; } if(depth>=2){ if(str[depth-2]=='1') return ; } getMin(str,depth+1); if(depth>0) turn(str[depth-1]); turn(str[depth]); if(depth+1<str.size()) turn(str[depth+1]); flag[depth]=true; getMin(str,depth+1); //回退,恢复状态 if(depth>0) turn(str[depth-1]); turn(str[depth]); if(depth+1<str.size()) turn(str[depth+1]); flag[depth]=false; }
此方法在hdu提交成功,在hero提交提示代码异常,不知道为什么了,调了半天!
还可以通过depth步为了确保depth-1为正面向上而主动翻动来进行优化。可以参见/article/2664050.html
相关文章推荐
- Hdu2209 翻纸牌游戏
- hdu2209翻纸牌游戏
- HDU2209:翻纸牌游戏(DFS)
- HDU2209:翻纸牌游戏(DFS)
- hdu2209翻纸牌游戏
- HDU2209-翻纸牌游戏
- HDU2209 翻纸牌游戏
- hdu2209翻纸牌游戏(双向bfs)
- 翻纸牌游戏 hdu2209
- csdn英雄会题解之第五届在线编程大赛月赛第三题:石子游戏 --多堆博弈游戏 多堆拈游戏
- HDU2209 翻纸牌游戏【技巧】
- hdu2209翻纸牌游戏(bfs+状态压缩)
- hdu2209 翻纸牌游戏--BFS & 位运算 & 状态压缩(待解决)
- HDU2209翻纸牌游戏(位运算+搜索)
- [题解]bzoj3240(NOI2013)矩阵游戏
- 【DFS+2-SAT验证】LibreOJ2305(NOI2017)[游戏]题解
- [题解]bzoj2328(HNOI2011)赛车游戏
- [NOIP2011]Mayan游戏 题解
- hdu 2209 翻纸牌游戏
- bzoj 1025 [SCOI2009] 游戏 题解