NOIP2011 提高組 Mayan
【解題思路】
因為時限為3秒,則考慮用搜尋。因為狀態數較多,明顯用BFS會爆,所以可以用DFS。剪枝的幾個地方:
1.一個格向左移動,等於它左邊的格向右移動,因此我們只要列舉每個格子向右移動便可。
2.若要調轉的兩個格子相同,則不調
3.若當前狀態某個顏色的數量小於3且不為0,那顯然這種顏色不可能被消除,則退出。
(編出的程式碼90,最後一個點超時,是在RNQOJ上測;我上網找過許多程式碼,放到RNQOJ上面,還沒有能AC的)
【程式碼】(望能幫忙找一下超時原因)
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int n;
struct node{
int x,y,p;
}s[10];
inline bool checkclear(int m[5][10])
{
for (int i=0;i<5;i++)
if (m[i][0]!=0) return 0;
return 1;
}
inline void print()
{
for (int i=0;i<n;i++)
printf("%d %d %d\n",s[i].x,s[i].y,s[i].p);
}
bool clearm(int tmp[5][10])
{
bool f=0,fl[5][10]={0};
for (int i=0;i<5;i++)
for (int j=0;j<5;j++)
if ((tmp[i][j]!=0)&&(tmp[i][j]==tmp[i][j+1])&&(tmp[i][j+1]==tmp[i][j+2]))
fl[i][j]=fl[i][j+1]=fl[i][j+2]=1;
for (int i=0;i<3;i++)
for (int j=0;j<7;j++)
if ((tmp[i][j]!=0)&&(tmp[i][j]==tmp[i+1][j])&&(tmp[i+1][j]==tmp[i+2][j]))
fl[i][j]=fl[i+1][j]=fl[i+2][j]=1;
for (int i=0;i<5;i++)
for (int j=0;j<7;j++)
{
if (fl[i][j])
{
f=1;
tmp[i][j]=0;
}
}
return f;
}
void drop(int tmp[5][10])
{
for (int i=0;i<5;i++)
for (int j=1;j<7;j++)
if ((tmp[i][j]!=0)&&(tmp[i][j-1]==0))
{
int p=j-1;
while ((p>=0)&&(tmp[i][p]==0))
{
swap(tmp[i][p+1],tmp[i][p]);
p--;
}
}
}
bool checkcolor(int m[5][10])
{
bool fl=1;
int sum[15]={0};
for (int i=0;i<5;i++)
for (int j=0;j<7;j++)
sum[m[i][j]]++;
for (int i=1;i<15;i++)
if ((sum[i]==1)||(sum[i]==2)) return 0;
return 1;
}
void dfs(int step,int m[5][10],int p,int q)
{
if (step==n)
{
if (checkclear(m))
{
print();
exit(0);
}
return;
}
if (!checkcolor(m)) return;
for (int i=0;i<4;i++)
{
for (int j=0;j<7;j++)
{
int tmp[5][10]={0};
memcpy(tmp,m,sizeof(tmp));
if (tmp[i][j]==tmp[i+1][j]) continue;
if (tmp[i][j]!=0)
{
s[step].x=i;
s[step].y=j;
s[step].p=1;
}else
{
s[step].x=i+1;
s[step].y=j;
s[step].p=-1;
}
swap(tmp[i][j],tmp[i+1][j]);
drop(tmp);
bool tf=0;
while (clearm(tmp))
{
drop(tmp);
tf=1;
}
if ((tf==0)&&(p==i)&&(q==j)) continue;
dfs(step+1,tmp,i,j);
}
}
}
int main()
{
scanf("%d",&n);
int m[5][10]={0};
for (int i=0;i<=4;i++)
{
int c=0,tmp;
while ((scanf("%d",&tmp)!=EOF)&&(tmp!=0))
m[i][c++]=tmp;
}
dfs(0,m,-1,-1);
printf("-1\n");
return 0;
}
相關文章
- NOIP2011提高組初賽不定項選擇第5題
- 洛谷P1003 [NOIP2011提高組] 鋪地毯 視訊題解
- 【NOIP2011模擬11.1】釣魚
- 專案組織——比較而後提高(轉)
- 題解--NOIP提高組2004 合併果子
- NOIP 提高組第一式第一題——玩具迷題
- Java提高篇(二):IO位元組流、字元流和處理流Java字元
- BF的資料結構題單-提高組——樹鏈剖分資料結構
- 2020.10.31【NOIP提高A組】模擬總結
- Python奇技淫巧—[2]—使用元組代替字典,同時為元組元素命名,提高可讀性Python
- Jzoj5459【NOIP2017提高A組衝刺11.7】密室
- 為元組中的每個元素命名,提高程式可讀性
- 1043 方格取數 2000年NOIP全國聯賽提高組
- 1058 合唱隊形 2004年NOIP全國聯賽提高組
- CCF-NOIP-2018 提高組(複賽) 模擬試題(一)
- CCF-NOIP-2018 提高組(複賽) 模擬試題(三)
- 1068 烏龜棋 2010年NOIP全國聯賽提高組
- P1525 [NOIP2010 提高組] 關押罪犯
- P2615 [NOIP2015 提高組] 神奇的幻方
- P1967 [NOIP2013 提高組] 貨車運輸 題解
- P2831 [NOIP2016 提高組] 憤怒的小鳥
- 洛谷 P1004 [NOIP2000 提高組] 方格取數
- 1099 字串變換 2002年NOIP全國聯賽提高組字串
- 洛谷題單指南-數學基礎問題-P2822 [NOIP2016 提高組] 組合數問題
- P1017 [NOIP2000 提高組] 進位制轉換 題解
- 洛谷 P1006 [NOIP2008 提高組] 傳紙條
- 洛谷 P1031 [NOIP2002 提高組] 均分紙牌 題解
- ElasticSearch(提高篇)Elasticsearch
- 提高SQL效能SQL
- [NOIP2017 提高組] 小凱的疑惑 / [藍橋杯 2013 省] 買不到的數目
- 洛谷題單指南-集合-P1525 [NOIP2010 提高組] 關押罪犯
- 紅帽更新產品組合,進一步提高雲原生應用開發的效能和規模
- Android提高--索引Android索引
- HTML5提高HTML
- 如何提高Java技能?Java
- 提高sqlmap爆破效率SQL
- CWCS提高流程效率
- [提高+] 模板口胡