POJ1543 + 1013 解题报告

    考察点:枚举法


    传送门:http://poj.org/problem?id=1543


POJ1543 完美立方

    题目描述:


Description

For hundreds of years Fermat's Last Theorem, which stated simply that for n > 2 there exist no integers a, b, c > 1 such that a^n = b^n + c^n, has remained elusively unproven. (A recent proof is believed to be correct, though it is still undergoing scrutiny.) It is possible, however, to find integers greater than 1 that satisfy the "perfect cube" equation a^3 = b^3 + c^3 + d^3 (e.g. a quick calculation will show that the equation 12^3 = 6^3 + 8^3 + 10^3 is indeed true). This problem requires that you write a program to find all sets of numbers {a,b,c,d} which satisfy this equation for a <= N.
Input

One integer N (N <= 100).
Output

The output should be listed as shown below, one perfect cube per line, in non-decreasing order of a (i.e. the lines should be sorted by their a values). The values of b, c, and d should also be listed in non-decreasing order on the line itself. There do exist several values of a which can be produced from multiple distinct sets of b, c, and d triples. In these cases, the triples with the smaller b values should be listed first.

    思想:只需要把4个参数中的所有值都扫描一遍,看是否符合要求。

Source Code:

//寻找完美立方等式
#include <iostream>
using namespace std;

int main()
{
    int n;
    cin >> n;
    int a, b, c, d;
    int three[101];
    for( int i = 0; i < 101; i++ )
        three[ i ] = i * i *i;
    int result;
    for( a = 3; a <= n; a++)
        for( b = 2; b <=n; b++ )
            for( c = 2; c <= n; c++ )
                for( d =2; d <= n; d++ )
                {
                    result = ( three[ b ] + three[ c ] + three[ d ] ) ;
                    if( three[ a ] == result )
                        cout << "Cube = " << a << ",Triple = (" << b << "," << c << "," << d <<")" << endl;
                }
}
结果:


题目要求输出的时候,b,c,d按照非降序排列输出,则b < c < d,修改代码,提交,AC通过。代码如下:

//寻找完美立方等式
#include <iostream>
using namespace std;

int main()
{
    int n;
    cin >> n;
    int a, b, c, d;
    int three[101];
    for( int i = 0; i < 101; i++ )
        three[ i ] = i * i *i;
    int result;
    for( a = 3; a <= n; a++)
        for( b = 2; b <=n; b++ )
            for( c = b; c <= n; c++ )
                for( d =c; d <= n; d++ )
                {
                    result = ( three[ b ] + three[ c ] + three[ d ] ) ;
                    if( three[ a ] == result )
                        cout << "Cube = " << a << ", Triple = (" << b << "," << c << "," << d <<")" << endl;
                }
}
当然,这样搜索的范围仍然太多,时间复杂度还是太大,我们需要做优化。

可以根据已知的东西来推出几个能够缩小范围的条件:

1.a一定大于b,c,d,所以bcd的for循环。只需要小于a就可以了,

2.在4层循环的第二层设立条件,如果 

three[a] < three[b] * 3;
则没有必要继续向下循环了,因为c,和d向下循环的话只会越来越大。继续修改代码"

//寻找完美立方等式
#include <iostream>
using namespace std;

int main()
{
    int n;
    cin >> n;
    int a, b, c, d;
    int three[101];
    for( int i = 0; i < 101; i++ )
        three[ i ] = i * i *i;
    int result;

    for( a = 3; a <= n; a++)
    {
        for( b = 2; b <a; b++ )
        {
            if( three[ a ] < three[ b ] * 3)
                break;
            for( c = b; c < a; c++ )
                for( d =c; d < a; d++ )
                {
                    result = ( three[ b ] + three[ c ] + three[ d ] ) ;
                    if( three[ a ] == result )
                        cout << "Cube = " << a << ", Triple = (" << b << "," << c << "," << d <<")" << endl;
                }
        }
    }
}


POJ1013  硬币问题:


传送门:http://poj.org/problem?id=1013


题目:

Description

Sally Jones has a dozen Voyageur silver dollars. However, only eleven of the coins are true silver dollars; one coin is counterfeit even though its color and size make it indistinguishable from the real silver dollars. The counterfeit coin has a different weight from the other coins but Sally does not know if it is heavier or lighter than the real coins. 
Happily, Sally has a friend who loans her a very accurate balance scale. The friend will permit Sally three weighings to find the counterfeit coin. For instance, if Sally weighs two coins against each other and the scales balance then she knows these two coins are true. Now if Sally weighs 
one of the true coins against a third coin and the scales do not balance then Sally knows the third coin is counterfeit and she can tell whether it is light or heavy depending on whether the balance on which it is placed goes up or down, respectively. 
By choosing her weighings carefully, Sally is able to ensure that she will find the counterfeit coin with exactly three weighings.
Input

The first line of input is an integer n (n > 0) specifying the number of cases to follow. Each case consists of three lines of input, one for each weighing. Sally has identified each of the coins with the letters A--L. Information on a weighing will be given by two strings of letters and then one of the words ``up'', ``down'', or ``even''. The first string of letters will represent the coins on the left balance; the second string, the coins on the right balance. (Sally will always place the same number of coins on the right balance as on the left balance.) The word in the third position will tell whether the right side of the balance goes up, down, or remains even.
Output

For each case, the output will identify the counterfeit coin by its letter and tell whether it is heavy or light. The solution will always be uniquely determined.
Sample Input

1 
ABCD EFGH even 
ABCI EFJK up 
ABIJ EFGH even 
Sample Output

K is the counterfeit coin and it is light. 

思想:

总共12个钱币,每个钱币要么是真币,要么是假币,假币要么比真币轻,要么比真币重。可以挨着对所有的去情形就行判断。

这里需要注意的一点是  右边高代表右边轻。。。在这点上卡了好久。。晕。审题不清楚。

代码:

#include <iostream>
#include <string.h>
using namespace std;
char leftInput[3][7],rightInput[3][7],result[3][5];//分别代表左边的3个输入,右边的3个,和3个结果

int main()
{

    bool IsHeavy( char );//判断钱币是否为重
    bool IsLight( char );//判断钱币是否为轻
    int n;//
    char c;//记录钱币的字母
    cin >> n;
    while( n )
    {
        cin.clear();
        for(int i = 0; i < 3; i++ )
            cin >> leftInput[i] >> rightInput[i] >> result[i] ;
        for( c = 'A'; c <= 'L'; c++ )//搜索空间,每个位置存在两种情况
        {
            if( IsHeavy( c ) )
            {
                cout << c << " is the counterfeit coin and it is heavy." << endl;
                break;
            }

            if( IsLight( c ) )
            {
                cout << c << " is the counterfeit coin and it is light." << endl;
                break;
            }

        }
        n--;
    }
}
bool IsHeavy(char c)
{

    for( int i = 0; i < 3; i++ )
    {
        switch( result[ i ][ 0 ])
        {
            //两边重量相等的情况,如果leftInput 和 rightInput中包含字符c,则肯定是真币,返回false
            case 'e': if( strchr( leftInput[ i ], c ) != NULL || strchr( rightInput[ i ],c ) != NULL )//如果leftInput和rightInput中存在c,则肯定不是假币
                            return false;
                            break;
            //右边轻的情况下,如果c是假币,且比真币重,则右边肯定包含假币,否则肯定会比左边轻,或者相等
            case 'u': if( strchr( leftInput[ i ], c ) == NULL )
                        return false;//如果不包含c ,则返回false
                        break;
            //右边重的情况下,如果c是假币,且比真币重,则左边肯定包含假币,否则肯定会比右边轻,或者相等
            case 'd': if( strchr( rightInput[ i ], c )  == NULL )
                        return false;
                        break;
        }
    }
    return true;
}
bool IsLight(char c)
{

    for( int i = 0; i < 3; i++ )
    {
        switch( result[ i ][ 0 ] )
        {
            //两边重量相等的情况,如oleftInput 和 rightInput中包含字符c,则肯定是真币,
            case 'e': if( strchr( leftInput[ i ], c ) != NULL || strchr( rightInput[ i ], c ) != NULL )//如果leftInput和rightInput中存在c,则肯定不是假币
                            return false;
                            break;
            //右边清的情况下,如果c是假币,且比真币轻,则左边肯定包含假币,否则肯定会比左边重,或者相等
            case 'u': if( strchr( rightInput[ i ], c ) == NULL )
                        return false;//如果不包含c ,则返回false
                        break;
            //右边重的情况下,如果c是假币,且比真币重,则右边肯定包含假币,否则肯定会比右边轻,或者相等
            case 'd': if( strchr( leftInput[ i ], c ) == NULL )
                        return false;
                        break;
        }
    }
    return true;
}

用字符串来处理:

#include <iostream>
#include <string>
using namespace std;
string leftInput[ 3 ] ,rightInput[ 3 ], result[ 3 ];//分别代表左边的3个输入,右边的3个,和3个结果

int main()
{

    bool IsHeavy( char );//判断钱币是否为重
    bool IsLight( char );//判断钱币是否为轻
    int n;//
    char c;//记录钱币的字母
    cin >> n;
    while( n )
    {
        cin.clear();
        for(int i = 0; i < 3; i++ )
            cin >> leftInput[i] >> rightInput[i] >> result[i] ;

        for( c = 'A'; c <= 'L'; c++ )//搜索空间,每个位置存在两种情况
        {
            if( IsHeavy( c ) )
            {
                cout << c << " is the counterfeit coin and it is heavy." << endl;
                break;
            }

            if( IsLight( c ) )
            {
                cout << c << " is the counterfeit coin and it is light." << endl;
                break;
            }

        }
        n--;
    }
}
bool IsHeavy(char c)
{

    for( int i = 0; i < 3; i++ )
    {
        switch( result[ i ][ 0 ])
        {
            //两边重量相等的情况,如果leftInput 和 rightInput中包含字符c,则肯定是真币,返回false
            case 'e': if( leftInput[ i ].find( c, 0 ) != -1 || rightInput[ i ].find( c, 0 ) != -1 )//如果leftInput和rightInput中存在c,则肯定不是假币
                            return false;
                            break;
            //右边轻的情况下,如果c是假币,且比真币重,则右边肯定包含假币,否则肯定会比左边轻,或者相等
            case 'u': if( leftInput[ i ].find( c, 0 ) == -1 )
                        return false;//如果不包含c ,则返回false
                        break;
            //右边重的情况下,如果c是假币,且比真币重,则左边肯定包含假币,否则肯定会比右边轻,或者相等
            case 'd': if(  rightInput[ i ].find( c, 0 )  == -1 )
                        return false;
                        break;
        }
    }
    return true;
}
bool IsLight(char c)
{

    for( int i = 0; i < 3; i++ )
    {
        switch( result[ i ][ 0 ] )
        {
            //两边重量相等的情况,如oleftInput 和 rightInput中包含字符c,则肯定是真币,
            case 'e': if( leftInput[ i ].find( c, 0 ) != -1 || rightInput[ i ].find( c, 0 ) != -1 )//如果leftInput和rightInput中存在c,则肯定不是假币
                            return false;
                            break;
            //右边清的情况下,如果c是假币,且比真币轻,则左边肯定包含假币,否则肯定会比左边重,或者相等
            case 'u':  if(  rightInput[ i ].find( c, 0 )  == -1 )
                        return false;//如果不包含c ,则返回false
                        break;
            //右边重的情况下,如果c是假币,且比真币重,则右边肯定包含假币,否则肯定会比右边轻,或者相等
            case 'd': if( leftInput[ i ].find( c, 0 ) == -1 )
                        return false;
                        break;
        }
    }
    return true;
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值