The Primes[USACO]

这道题无论横着,竖着,一行/列来整体放都会超时,想不到什么好办法。只好写了个超长的switch case语句,想清楚瞅仔细,就省得调试麻烦了。

//00-17-11-18-03
//21-04-22-08-15
//12-19-05-20-10
//23-07-24-06-16
//02-13-09-14-01

上图是处理顺序,从00--24.  实际只用了15个case,因为有一些是可以计算出来的。之所以是这个顺序是为了把循环次数小的case放前头。运行速度还是很快的。

 

 

/*
ID: zhangyc1
LANG: C++
TASK: prime3
*/
//00-17-11-18-03
//21-04-22-08-15
//12-19-05-20-10
//23-07-24-06-16
//02-13-09-14-01
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;

stringstream os;
ofstream fileout("prime3.out");

int nFirstNum, nCommonSum;
// 因为sqrt(99999)=316.23,计算base为
int arrBasePrimeSet[100], nSizeBasePrimeSet = 0;
bool arrIsPrime[10][10][10][10][10];
bool bFound = false;
int arrMul[5] = {10000, 1000, 100, 10, 1};
int arrLastNum[4] = {1, 3, 7, 9};
int arrSumLine[5], arrSumCol[5], arrSumDia[2];
vector<string> vtRs;
int arrNum[5][5];

void getBasePrimeSet()
// 筛法求2-317内素数
{
    bool arrIsPrime[318];
    memset(arrIsPrime, 1, sizeof(arrIsPrime));
    int nPos = 2;
    while (nPos < 318)
    {
        arrBasePrimeSet[nSizeBasePrimeSet] = nPos;
        nSizeBasePrimeSet++;

        int nThresh = 317 / nPos;
        for (int i = 2; i < nThresh; i++)
        {
            arrIsPrime[i * nPos] = false;
        }
        nPos++;
        while (nPos < 318 && arrIsPrime[nPos] == false)
            nPos++;
    }
}
// 10000至99999内满足和为nCommonSum
void getValidPrimeSet()
{
    int arrDigit[5];
    for (int i = 10001; i <= 99999; i++)
    {
        int nTemp = i;
        for (int j = 4; j >= 0; j--)
        {
            arrDigit[j] = nTemp % 10;
            nTemp /= 10;
        }

        if (arrDigit[0] + arrDigit[1] + arrDigit[2] + arrDigit[3] + arrDigit[4] == nCommonSum)
        {
            bool bValid = true;
            for (int j = 0; j < nSizeBasePrimeSet; j++)
            {
                if (i % arrBasePrimeSet[j] == 0)
                {
                    bValid = false;
                    break;
                }
            }
            if (bValid)
            {
                arrIsPrime[arrDigit[0]][arrDigit[1]][arrDigit[2]][arrDigit[3]][arrDigit[4]] = true;
            }
        }
    }
}

void prepairData()
{
    ifstream filein("prime3.in");
    filein >> nCommonSum >> nFirstNum;
    filein.close();
    memset(arrIsPrime, 0, sizeof(arrIsPrime));
}

void recordRs()
{
    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            os << arrNum[i][j];
        }
    }
    string str;
    os >> str;
    os.clear();
    vtRs.push_back(str);
}

void dfs(int nDepth)
{
    switch (nDepth)
    {
    case 0:
        arrNum[0][0] = nFirstNum;
        arrSumLine[0] = nFirstNum;
        arrSumCol[0] = nFirstNum;
        arrSumDia[0] = nFirstNum;
        dfs(1);
    	break;
    case 1:
        for (int i = 0; i < 4; i++)
        {
            arrNum[4][4] = arrLastNum[i];
            arrSumLine[4] += arrLastNum[i];
            arrSumCol[4] += arrLastNum[i];
            arrSumDia[0] += arrLastNum[i];
            if (arrSumLine[4] <= nCommonSum && arrSumCol[4] <= nCommonSum && arrSumDia[0] <= nCommonSum)
            {
                dfs(2);
            }
            arrSumLine[4] -= arrLastNum[i];
            arrSumCol[4] -= arrLastNum[i];
            arrSumDia[0] -= arrLastNum[i];
        }
        break;
    case 2:
        for (int i = 0; i < 4; i++)
        {
            arrNum[4][0] = arrLastNum[i];
            arrSumLine[4] += arrLastNum[i];
            arrSumCol[0] += arrLastNum[i];
            arrSumDia[1] += arrLastNum[i];
            if (arrSumLine[4] <= nCommonSum && arrSumCol[0] <= nCommonSum && arrSumDia[1] <= nCommonSum)
            {
                dfs(3);
            }
            arrSumLine[4] -= arrLastNum[i];
            arrSumCol[0] -= arrLastNum[i];
            arrSumDia[1] -= arrLastNum[i];
        }
        break;
    case 3:
        for (int i = 0; i < 4; i++)
        {
            arrNum[0][4] = arrLastNum[i];
            arrSumLine[0] += arrLastNum[i];
            arrSumCol[4] += arrLastNum[i];
            arrSumDia[1] += arrLastNum[i];
            if (arrSumLine[0] <= nCommonSum && arrSumCol[4] <= nCommonSum && arrSumDia[1] <= nCommonSum)
            {
                dfs(4);
            }
            arrSumLine[0] -= arrLastNum[i];
            arrSumCol[4] -= arrLastNum[i];
            arrSumDia[1] -= arrLastNum[i];
        }
        break;
    case 4:
        for (int i = 0; i <= 9; i++)
        {
            arrNum[1][1] = i;
            arrSumLine[1] += i;
            arrSumCol[1] += i;
            arrSumDia[0] += i;
            if (arrSumLine[1] <= nCommonSum && arrSumCol[1] <= nCommonSum && arrSumDia[0] <= nCommonSum)
            {
                dfs(5);
            }
            arrSumLine[1] -= i;
            arrSumCol[1] -= i;
            arrSumDia[0] -= i;
        }
        break;
    case 5:
        for (int i = 0; i <= 9; i++)
        {
            int nLeft = nCommonSum - i - arrSumDia[0];
            if (nLeft >= 0 && nLeft <= 9 && arrIsPrime[arrNum[0][0]][arrNum[1][1]][i][nLeft][arrNum[4][4]])
            {
                arrNum[2][2] = i;
                arrNum[3][3] = nLeft;
                arrSumLine[2] += i, arrSumLine[3] += nLeft;
                arrSumCol[2] += i, arrSumCol[3] += nLeft;
                arrSumDia[0] = nCommonSum;
                arrSumDia[1] += i;
                dfs(7);
                arrSumLine[2] -= i, arrSumLine[3] -= nLeft;
                arrSumCol[2] -= i, arrSumCol[3] -= nLeft;
                arrSumDia[0] = nCommonSum - i  - nLeft;
                arrSumDia[1] -= i;
            }
        }
        break;
    case 7:
        for (int i = 0; i <= 9; i++)
        {
            int nLeft = nCommonSum - i - arrSumDia[1];
            if (nLeft >= 0 && nLeft <= 9 && arrIsPrime[arrNum[4][0]][i][arrNum[2][2]][nLeft][arrNum[0][4]])
            {
                arrNum[3][1] = i;
                arrNum[1][3] = nLeft;
                arrSumLine[3] += i, arrSumLine[1] += nLeft;
                arrSumCol[1] += i, arrSumCol[3] += nLeft;
                arrSumDia[1] = nCommonSum;
                dfs(9);
                arrSumLine[3] -= i, arrSumLine[1] -= nLeft;
                arrSumCol[1] -= i, arrSumCol[3] -= nLeft;
                arrSumDia[1] = nCommonSum - i  - nLeft;
            }
        }
        break;
    case 9:
        for (int i = 0; i < 4; i++)
        {
            arrNum[4][2] = arrLastNum[i];
            arrSumLine[4] += arrLastNum[i];
            arrSumCol[2] += arrLastNum[i];
            if (arrSumLine[4] <= nCommonSum && arrSumCol[2] <= nCommonSum)
            {
                dfs(10);
            }
            arrSumLine[4] -= arrLastNum[i];
            arrSumCol[2] -= arrLastNum[i];
        }
        break;
    case 10:
        for (int i = 0; i < 4; i++)
        {
            arrNum[2][4] = arrLastNum[i];
            arrSumLine[2] += arrLastNum[i];
            arrSumCol[4] += arrLastNum[i];
            if (arrSumLine[2] <= nCommonSum && arrSumCol[4] <= nCommonSum)
            {
                dfs(11);
            }
            arrSumLine[2] -= arrLastNum[i];
            arrSumCol[4] -= arrLastNum[i];
        }
        break;
    case 11:
        for (int i = 1; i <= 9; i++)
        {
            arrNum[0][2] = i;
            arrSumLine[0] += i;
            arrSumCol[2] += i;
            if (arrSumLine[0] <= nCommonSum && arrSumCol[2] <= nCommonSum)
            {
                dfs(12);
            }
            arrSumLine[0] -= i;
            arrSumCol[2] -= i;
        }
        break;
    case 12:
        for (int i = 1; i <= 9; i++)
        {
            arrNum[2][0] = i;
            arrSumLine[2] += i;
            arrSumCol[0] += i;
            if (arrSumLine[2] <= nCommonSum && arrSumCol[0] <= nCommonSum)
            {
                dfs(13);
            }
            arrSumLine[2] -= i;
            arrSumCol[0] -= i;
        }
        break;
    case 13:
        for (int i = 0; i < 4; i++)
        {
            int nLeft = nCommonSum - arrSumLine[4] - arrLastNum[i];
            if (nLeft > 0 && nLeft <= 9 && arrIsPrime[arrNum[4][0]][arrLastNum[i]][arrNum[4][2]][nLeft][arrNum[4][4]])
            {
                arrNum[4][1] = arrLastNum[i], arrNum[4][3] = nLeft;
                arrSumLine[4] = nCommonSum;
                arrSumCol[1] += arrLastNum[i], arrSumCol[3] += nLeft;
                dfs(15);
                arrSumLine[4] -= nLeft + arrLastNum[i];
                arrSumCol[1] -= arrLastNum[i], arrSumCol[3] -= nLeft;
            }
        }
        break;
    case 15:
        for (int i = 0; i < 4; i++)
        {
            int nLeft = nCommonSum - arrSumCol[4] - arrLastNum[i];
            if (nLeft > 0 && nLeft <= 9 && arrIsPrime[arrNum[0][4]][arrLastNum[i]][arrNum[2][4]][nLeft][arrNum[4][4]])
            {
                arrNum[1][4] = arrLastNum[i], arrNum[3][4] = nLeft;
                arrSumCol[4] = nCommonSum;
                arrSumLine[1] += arrLastNum[i], arrSumLine[3] += nLeft;
                dfs(17);
                arrSumCol[4] -= nLeft + arrLastNum[i];
                arrSumLine[1] -= arrLastNum[i], arrSumLine[3] -= nLeft;
            }
        }
        break;
    case 17:
        for (int i = 1; i <= 9; i++)
        {
            int nLeft1 = nCommonSum - arrSumLine[0] - i;
            int nLeft2 = nCommonSum - arrSumCol[1] - i;
            int nLeft3 = nCommonSum - arrSumLine[2] - nLeft2;
            if (nLeft1 > 0 && nLeft1 <= 9  && nLeft2 >= 0 && nLeft2 <= 9 && nLeft3 >= 0 && nLeft3 <= 9 && 
                nLeft1 + nLeft3 + arrSumCol[3] == nCommonSum && 
                arrIsPrime[arrNum[0][0]][i][arrNum[0][2]][nLeft1][arrNum[0][4]] &&
                arrIsPrime[arrNum[2][0]][nLeft2][arrNum[2][2]][nLeft3][arrNum[2][4]] &&
                arrIsPrime[i][arrNum[1][1]][nLeft2][arrNum[3][1]][arrNum[4][1]] &&
                arrIsPrime[nLeft1][arrNum[1][3]][nLeft3][arrNum[3][3]][arrNum[4][3]])
            {
                arrNum[0][1] = i, arrNum[0][3] = nLeft1, arrNum[2][1] = nLeft2, arrNum[2][3] = nLeft3;
                arrSumLine[0] = arrSumLine[2] = arrSumCol[1] = arrSumCol[3] = nCommonSum;
                dfs(21);
                arrSumLine[0] -= i + nLeft1, arrSumLine[2] -= nLeft2 + nLeft3;
                arrSumCol[1] -= i + nLeft2, arrSumCol[3] -= nLeft1 + nLeft3;
            }
        }
        break;
    case 21:
        for (int i = 1; i <= 9; i++)
        {
            int nLeft1 = nCommonSum - arrSumLine[1] - i;
            int nLeft2 = nCommonSum - arrSumCol[0] - i;
            int nLeft3 = nCommonSum - arrSumLine[3] - nLeft2;
            if (nLeft2 > 0 && nLeft2 <= 9 && nLeft1 >= 0 && nLeft1 <= 9 && nLeft3 >= 0 && nLeft3 <= 9 && 
                nLeft1 + nLeft3 + arrSumCol[2] == nCommonSum && 
                arrIsPrime[i][arrNum[1][1]][nLeft1][arrNum[1][3]][arrNum[1][4]] &&
                arrIsPrime[nLeft2][arrNum[3][1]][nLeft3][arrNum[3][3]][arrNum[3][4]] &&
                arrIsPrime[arrNum[0][0]][i][arrNum[2][0]][nLeft2][arrNum[4][0]] &&
                arrIsPrime[arrNum[0][2]][nLeft1][arrNum[2][2]][nLeft3][arrNum[4][2]])
            {
                arrNum[1][0] = i, arrNum[3][0] = nLeft2, arrNum[1][2] = nLeft1, arrNum[3][2] = nLeft3;
                recordRs();
            }
        }
        break;
    }
}

void process()
{
    getBasePrimeSet();
    getValidPrimeSet();
    dfs(0);
    if (vtRs.size() == 0)
    {
        fileout << "NONE\n";
    }
    else
    {
        sort(vtRs.begin(), vtRs.end());
        string strTemp;
        for (vector<string>::const_iterator it = vtRs.begin(); it != vtRs.end(); it++)
        {
            if (it != vtRs.begin())
            {
                fileout << endl;
            }
            strTemp = *it;
            fileout << strTemp.substr(0, 5) << "\n" << strTemp.substr(5, 5) << "\n" << strTemp.substr(10, 5) << "\n" << strTemp.substr(15, 5) << "\n"
                << strTemp.substr(20, 5) << "\n";
        }
    }
}

int main(){
    prepairData();
    process();
    fileout.close(); 
    return 0;
}

  

转载于:https://www.cnblogs.com/doublemystery/archive/2013/04/11/3015053.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值