UVa11126 - Relaxed Golf

Problem I
Relaxed Golf 
Input: 
Standard Input

Output: Standard Output

 Golf and sex are about the only things
you can enjoy without being good at.

Jimmy Demaret

Relaxed Golf is a solitaire game. Cards are dealt face up in 7 columns of 5 cards each. The remaining 17 cards are put face down into the draw pile. Suits don't matter, so we will represent cards using integers between 1 (Ace) and 13 (King), four of each. For this problem, we will know the order of the cards in the draw pile. Finally, we have the discard pile. The goal of the game is to put all of the cards into the discard pile.

A move consists of playing a card from the top of the draw pile or the top of one of the non-empty columns on top of the discard pile. When playing from the columns, the rank of card played must differ by exactly one from the rank of the card on top of the discard pile. In Relaxed Golf (as opposed to regular Golf), wraparound is allowed. Kings may be played on top of aces, and vice versa. We can play cards from the draw pile onto the discard pile at any time. In fact, the first move must be from the draw pile.

Input
The input starts with a line giving the number of test cases, N. Each test case consists of 6 lines. The first 5 lines have 7 cards each and list the cards in the columns, with the top cards appearing on the 5th line. The 6th line lists the cards in the draw pile, from bottom to top.

Output
For each test case, output one line containing "Case #x:" followed by either "Yes" or "No", depending on whether the puzzle can be solved or not.

Sample Input

Sample Output

2

 9 10  9 10  9 10  9

 7  8  7  8  7  8  7

 5  6  5  6  5  6  5

 3  4  3  4  3  4  3

 1  2  1  2  1  2  1

13 13 13 13 12 12 12 12 11 11 11 11 10 8 6 4 2

 5  5  5 13 13 13 13

 7  7  7  6  6  6  6

 9  9  8  8  8  8  7

11 10 10 10 10  9  9

12 12 12 12 11 11 11

 1  1  1  1  2  2  2 2 3 3 3 3 4 4 4 4 5

 

Case #1: Yes

Case #2: No

 


Problemsetter: Igor Naverniouk
Special Thanks: Joachim Wulff


题目大意就是  有1个draw pile 和 7个普通的pile 每次只能取最外面的牌(ace~king) 且每次从7堆牌中取的牌与上一次取的牌必须差1,(ace和king 也算差1)或者直接从draw pile取一张最外面的,问是否有一种取法能使所有的牌都取完且一开始只能取draw pile的牌!

分析: dfs(int last,int draw,int c1,int c2,int c3,int c4,int c5,int c6,int c7) 用记忆化可以迅速秒分析出状态,这一题最大的问题是初始化,因为要开int dp[14][17][6][6][6][6][6][6][6]这么大的数组,如果每次都初始化肯定会TLE!可以用记录访问的方法来避免每次都memset 从而避免超时

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;
int dp[14][17][6][6][6][6][6][6][6],pat;
int num[8][18];
bool can(int x,int y){
    return abs(x-y)==12||abs(x-y)==1;
}
bool dfs(int last,int draw,int c1,int c2,int c3,int c4,int c5,int c6,int c7){
    int &t = dp[last][draw][c1][c2][c3][c4][c5][c6][c7];
    if(t==pat) return 0;
    t = pat;
    if(draw+c1+c2+c3+c4+c5+c6+c7==0) return 1;
    if(draw>0) if(dfs(num[0][draw],draw-1,c1,c2,c3,c4,c5,c6,c7)) return 1;
    if(c1>0&&can(num[1][c1],last)&&dfs(num[1][c1],draw,c1-1,c2,c3,c4,c5,c6,c7))  return 1;
    if(c2>0&&can(num[2][c2],last)&&dfs(num[2][c2],draw,c1,c2-1,c3,c4,c5,c6,c7))  return 1;
    if(c3>0&&can(num[3][c3],last)&&dfs(num[3][c3],draw,c1,c2,c3-1,c4,c5,c6,c7))  return 1;
    if(c4>0&&can(num[4][c4],last)&&dfs(num[4][c4],draw,c1,c2,c3,c4-1,c5,c6,c7))  return 1;
    if(c5>0&&can(num[5][c5],last)&&dfs(num[5][c5],draw,c1,c2,c3,c4,c5-1,c6,c7))  return 1;
    if(c6>0&&can(num[6][c6],last)&&dfs(num[6][c6],draw,c1,c2,c3,c4,c5,c6-1,c7))  return 1;
    if(c7>0&&can(num[7][c7],last)&&dfs(num[7][c7],draw,c1,c2,c3,c4,c5,c6,c7-1))  return 1;
    return 0;
}
int main(){
    int ncase,T=1;
    cin >> ncase;
    memset(dp,0,sizeof dp);
    pat = 0;
    while(ncase--){
        for(int i = 1; i <= 5; i++)
            for(int j = 1; j <= 7; j++) cin >> num[j][i];

        for(int i = 1; i <= 17; i++) cin >> num[0][i];
        printf("Case #%d: ",T++);
        pat++;
        if(dfs(num[0][17],16,5,5,5,5,5,5,5)) cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值