UVALive 6163(暴力枚举)

这道题我的做法就是枚举这四个数的所有排列所有运算所有计算顺序。

略有考验代码能力,不能漏掉情况,注意模块化的思想,一些功能写成函数调试的时候结构清晰好分析。

比赛时没有AC是对next_permutation()函数理解的不透,根本没有想到是没有从最小字典序开始枚举的问题。

就是next_permutation()函数是从当前顺序枚举到字典序最大的,而我开始时do里面的a数组不一定是字典序最小的,但是next_permutation()函数一定是从当前字典序往最大的枚举,所以漏掉了字典序很小的那些情况。所以我在do里面第一步加一个sort排序就AC了。

next_permutation()函数是从当前顺序一直枚举到字典序最大的(按字典序递增的顺序),没有更大的排列了就返回false,否则改了排列顺序以后返回true。

prev_permutation()函数是从当前顺序一直枚举到字典序最小的(按字典序递减的顺序),没有更小的排列了就返回false,否则改了排列顺序以后返回true。

这也是next和prev的意思,所谓“下一个”和“上一个”,就是字典序刚好比它大一点的排列和刚好比它小一点的排列。

平时学知识一知半解,比赛时就遭报应了。。。。。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
#define INF 1000000000
#define eps 1e-8
#define pii pair<int,int>
#define LL long long int
int n,a[4];
char in[4];
bool deal();
bool cal(int i,int j,int k);
int g(int x,int y,int d);
int main()
{
    //freopen("in1.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    while(scanf("%d",&n)==1&&n)
    {
        bool ans=true;
        for(int i=1; i<=n; i++)
        {
            scanf("%s",in);
            if(ans==false)
                continue;
            else
            {
                a[0]=in[0]-‘0‘;
                a[1]=in[1]-‘0‘;
                a[2]=in[2]-‘0‘;
                a[3]=in[3]-‘0‘;
                if(deal()==false)//这四个数弄不出10
                {
                    ans=false;
                }
            }
        }
        if(ans==true)
            printf("TRUE\n");
        else
            printf("BUSTED\n");
    }
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}
bool deal()
{
    sort(a,a+4);//没有这句就WA了
    do
    {
        for(int i=0; i<4; i++)
        {
            for(int j=0; j<4; j++)
            {
                for(int k=0; k<4; k++)
                {
                    //三个for枚举所有运算符的组合
                    if(cal(i,j,k))
                    {
                        return true;
                    }
                }
            }
        }
    }
    while(next_permutation(a,a+4));//枚举四个数的所有排列
    return false;
}
bool cal(int i,int j,int k)
{
    int t1=g(a[0],a[1],i);
    int t2=g(a[1],a[2],j);
    int t3=g(a[2],a[3],k);
    //接下来枚举所有运算次序
    if(g(t1,t3,j)==10)//k,i,j
        return 1;
    else if(  g( g(a[0],t2,i),a[3],k)==10 )//j,i,k
        return 1;
    else if(  g( g(t1,a[2],j),a[3],k)==10 )//i,j,k
        return 1;
    /*else if(  g( g(a[0],a[1],i),t3,j)==10 )//i,k,j
        return 1;*/
    else if(  g( a[0],g(t2,a[3],k),i)==10 )//j,k,i
        return 1;
    else if(  g( a[0],g(a[1],t3,j),i)==10 )//k,j,i
        return 1;
    else
        return 0;
}
int g(int x,int y,int d)
{
    if(d==0)
        return x+y;
    else if(d==1)
        return x-y;
    else if(d==2)
        return x*y;
    else
    {
        if(y)
            return x/y;
        else
            return 0;//分母为0不能进行除法,那这种情况肯定不行,那我就看成乘以0返回。
    }
}

UVALive 6163(暴力枚举),布布扣,bubuko.com

时间: 2024-10-13 03:06:26

UVALive 6163(暴力枚举)的相关文章

Gym 101194L / UVALive 7908 - World Cup - [三进制状压暴力枚举][2016 EC-Final Problem L]

题目链接: http://codeforces.com/gym/101194/attachments https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5930 题意: 现有四支队伍两两打比赛,总共就是打六场比赛,每场比赛赢的队伍可得 $3$ 分,输的队伍得 $0$ 分,平局则两个队各得 $1$ 分. 现在给出四个队伍最终的积分

hdu5616 暴力枚举

2017-08-25 20:08:54 writer:pprp 题目简述: ? HDU 5616? n个砝码,可以放在天平左右两侧或不放? m次询问,每次询问是否可以测出给定重量? 1 ≤ n ≤ 20? 1 ≤ m ≤ 100 这道题采用枚举的思路的话实现起来还是有点困难的, 要实现的功能是对每个砝码进行处理,加到左边, 加到右边,或者是不加 看了大神的代码,感觉很巧妙, 设置了两个标记数组 vis1[2005], vis2[2005] 一个vis1用来记录当前已经可以实现的重量 另一个vis

hdu4282A very hard mathematic problem 暴力枚举

//给出k //找x,y,z使得x^z+y^z+x*y*z = k //x,y,z都为正整数x<y,z>1问有多少种方法 //当z = 2时,可以看到左边是一个完全平方 //而当z>=3时,可以暴力枚举x,y //由于k<2^31所以x<2^(31/3)枚举复杂度可以过 #include<cstdio> #include<cstring> #include<iostream> #include<cmath> using name

hdu 5247 找连续数【暴力枚举】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5247 分析:这道题是2015百度之星初赛1的2题,当时没看这道题 是队友看的,比完以后也做了一下,思路大体都是一样的,就是 暴力枚举,因为k<=1000,那么我们可以每一点x为起点跑[x,x+999] 这段区间,把每得到一段连续的子区间[x,?],则num[len]++(len=size([x,?])); 这样就可以了,最后num数组里就是对应的答案 献上代码: #include<stdio.h&

HDU 4770 Lights Against Dudely 暴力枚举+dfs

又一发吐血ac,,,再次明白了用函数(代码重用)和思路清晰的重要性. 11779687 2014-10-02 20:57:53 Accepted 4770 0MS 496K 2976 B G++ czy Lights Against Dudely Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1360    Accepted Subm

ZOJ3818-Pretty Poem(暴力枚举)

题目链接 题意:求所给字符串是否符合ABABA或者ABABCAB的形式,如果可以的话输出Yes,不可以的话为No. 思路:暴力枚举A和B的长度,再用从长度减去3倍的AB长度,即为C的长度,看组合而成的字符串是否与给定的相等.在这里string中的substr函数是个好东西. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <a

uva10892(暴力枚举)

把n的所有因子求出来,总数不会太多,所以直接O(n2)的暴力枚举所有对行不行. 有几个细节要注意,详见代码. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<map> #include<set> #include<vector> #include<algorit

暴力枚举 + 24点 --- hnu : Cracking the Safe

Cracking the Safe Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit users: 46, Accepted users: 12 Problem 12886 : No special judgement Problem description Secret agent Roger is trying to crack a safe containing evil Syr

HNU 12886 Cracking the Safe(暴力枚举)

题目链接:http://acm.hnu.cn/online/?action=problem&type=show&id=12886&courseid=274 解题报告:输入4个数,要你判断用 + .- . * ./.四种运算能不能得到一个结果为24的式子,可以用括号. 解释一下测试的第四组样例:应该是6 / (1 - 3 / 4) 暴力枚举三种符号分别是什么,然后枚举这三种符号运算的顺序,然后枚举这四个数字的24种排列方式,时间是4^3 * 6 * 24 然后注意要用double型,