1. 程式人生 > >藍橋杯2016決賽 湊平方數

藍橋杯2016決賽 湊平方數

更新:17.5.23     去年寫的帖子,好幾個評論以為之前做的是錯的,剛比完賽就知道錯在哪裡了,後面的返回型別只要改為LL就好了,之前是因為越界原因,藍橋杯尤其注意這些小細節,其他沒什麼含量,直接上暴力。。。

最倒黴的一次,我直接也是醉了,想在想起來都悔死了,263,這個數字我絕對不會忘掉,一等獎一步之遙,剛考完的時候還在想怎麼會這樣,最不能確定的題目就是這道了,考試的時候感覺挺簡單的,之後聊的時候甚至有點納悶,怎麼還都最不出來呢,結果最後自己卻是錯掉了,如果不會也就算了,但是全部結果只因為一個LL,兩個字母就決定了最終的結果,也是悔死了。。。

但是決賽已經結束,ACM省賽全力以赴吧。。。

8個人,額,就8個人 。 。 。 。 。 。 。 。 。。 。 。 。。 。 。 。。  。。 。 。 。。 。 。 。。 。。 。 。 。。 。。 。 。 

正確程式碼:

#include <iostream>
#include <fstream>
#include <cstring>
#define LL long long
using namespace std;
bool mark[100]; ///標記哪些數字出現過
LL res[100],sum=0;  ///res儲存結果
bool tmpmark[10];   ///臨時標記
bool judge(LL x){  ///判斷這個數是否是出現過
  memset(tmpmark,0,sizeof(tmpmark));
  if(x==0){
    if(mark[0] == 1)
        return false;
    return true;
  }
  while(x!=0){
    if(mark[x%10] || tmpmark[x%10])
        return false;
    tmpmark[x%10] = 1;
    x/=10;
  }
  return true;
}

int update(LL x,int coun){///用於修改哪些數字已經出現過 ///就錯了這個地方的一個LL,兩個字母啊啊啊啊啊啊啊 啊啊啊啊啊啊 啊啊 啊啊啊啊 啊啊 啊啊啊啊 啊啊啊啊 啊 啊啊 啊啊啊
  if(x==0){
    mark[x] = 1;
    coun++;
    return coun;
  }
  while(x!=0){
    mark[x%10] = 1;
    x/=10;
    coun++;
  }
  return coun;
}

void reupdate(LL x){  ///用於還原上一個標記狀態
  if(x==0){
    mark[x] = 0;
    return ;
  }
  while(x!=0){
    mark[x%10] = 0;
    x/=10;
  }
}

void dfs(int coun,int rescoun,LL last){
  if(coun == 10){
    for(int i=0;i<rescoun;i++)
        cout<<res[i]<<' ';
    cout<<">>>"<<sum<<endl;
    sum++;
    return ;
  }
  for(LL i=last;i<=100000;i++){
    if(judge(i*i)){  ///判斷是否出現了該數裡面含有的數字
        int tmpcoun = update(i*i,coun);  ///更新新狀態(包含i*i)
        res[rescoun] = i*i;
        dfs(tmpcoun,rescoun+1,i+1);
        reupdate(i*i);   ///還原上一狀態
    }
  }
}
int main (){
    memset(mark,0,sizeof(0));
    dfs(0,0,0);
    cout<<sum;
    return 0;
}