申請SAE

如果您發現本博客的外觀很難看,那是因為部分外觀文件被中國.國家.防火.牆屏.蔽所致!
請翻~牆!

我的Wordpress博客的地址: http://zhuyf.tk/

2011年11月19日 星期六

[搜索][最短路徑]BYVoid魔獸世界模擬題Stage.1 埃雷薩拉斯的尋寶 eldrethalas 解題報告

【問題描述】
一萬兩千年前,精靈還是在艾薩拉女王的統治下,辛德拉是女王手 下一名很有地位的法師。他受任建造了一座城市,來保存女王的法師們進行魔法研究的成果和法術物品。這個城市就是埃雷薩拉斯。永恆之井的爆炸,使這裏的精靈 和總部聯繫中斷,並失去了永恆之井的水做爲能量的來源。辛德拉的後人爲了滿足魔法的慾望,捕獵了一個惡魔,伊莫塔爾,並以水晶塔建造了一個帶有能量平衡係 統的結界監獄,水晶塔從惡魔身上吸取能量,一部分維持結界監獄,一部分可以讓精靈狂熱者吸收。近萬年平安無事。但是現在,惡魔的能量被消耗得越來越多,最 終變得不穩定,已經難以維持結界監獄的消耗。統治這裏的托爾塞林王子開始下令屠殺。只有少數狂熱者之外的其他人都要死,以減少魔法能量的消耗。

終於,強大的戈多克食人魔入侵了埃雷薩拉斯,並殺死了大量的精靈。他們把這裏當作他們的領地,叫做厄運之槌。面臨滅頂之災的精靈們把他們祖先留下的寶藏用魔法結界藏了起來,以防戈多克食人魔搶走。
作爲一名勇敢的探險者,你悄悄來到了埃雷薩拉斯,來尋找傳說中的寶藏。終於,你看到了寶藏,他就在你的前方不遠處。但是你不能貿然前進,因爲路上有着強大的魔法結界。這些結界根據能量的不同分爲P種,踏入每種結界,你都會受到一定的傷害。爲了拿到寶藏,這些傷害算不了什麼。但是你要儘可能地減少傷害,請你設計一條路綫,使你穿越結界獲取寶藏受到的傷害最少。

下面是一個魔法結界能量示意圖,結界是一個正方形,內部有P種不同的能量,每種字母表示一種能量。你從最上端開始走,每次能走到與你所在的位置鄰接的一個單元格,或者在同種能量結界中任意傳送。重複進入同一種能量結界不會再次受到傷害。

|AAABBC|
|ABCCCC|
|AABBDD|
|EEEEEF|
|EGGEFF|
|GGFFFF|

你有H點生命值,請你在貿然行動之前先判斷是否能夠活着(生命值大於0)穿越結界拿到寶藏,如果能夠,請求出最大的生命值。
輸入格式
第1行 三個非負整數 N P H。N爲結界的邊長,P爲不同的能量結界的數量,H爲你的生命值。
第2-P+1行 每行一個非負整數,表示走到該種能量結界受到的傷害值。
第P+2至第P+2+N行 每行N個正整數,爲地圖上該單元格的能量種類的編號,編號爲1..P。
輸出格式
如果你能夠穿越結界到達對岸的寶藏,輸出最多剩餘的生命值。如果不能穿越,輸出NO。
樣例輸入
6 7 10
3
1
2
2
1
1
3
1 1 1 2 2 3
1 2 3 3 3 3
1 1 2 2 4 4
5 5 5 5 5 6
5 7 7 5 6 6
7 7 6 6 6 6
樣例輸出
7
樣例說明
路綫爲
起始-2-5-6-目標
1 1 1 2 2 3
1 2 3 3 3 3
1 1 2 2 4 4
5 5 5 5 5 6
5 7 7 5 6 6
7 7 6 6 6 6
數據規模
對於40%數據
4<=N<=10
對於100%數據
4<=N<=50
1<=P<=N*N
0<=H<=200000000

【分析】
搜索+最短路,把每個結界縮成一個點,通過搜索找出與每個結界相鄰接的結界,就這樣構圖就行了。然後用Dijkstra等O(N^2)算法求最短路即可。
【我的代碼】
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN=2505;
const int MAX=0x7fffffff;
int Mat[MAXN][MAXN];
int Val[MAXN][MAXN];
int Abut[MAXN]={0};
bool used[MAXN][MAXN];
bool flag[MAXN]={false};
int dist[MAXN];
int Map[62][62];
int step[4][2]={{0,1},{0,-1},{1,0},{-1,0}};

int N,P,H,E;
int Magic[62];

void init()
{
    scanf("%d %d %d",&N,&P,&H);
   
    E=P+1;
   
    for (int i=1;i<=P;i++)
        scanf("%d",&Magic[i]);
   
    for (int i=1;i<=N;i++)
        for (int j=1;j<=N;j++)
            scanf("%d",&Map[i][j]);
   
    for (int i=1;i<=P;i++)
        for(int j=1;j<=P;j++)
            used[i][j]=false;
       
    bool used[MAXN];
    memset(used,false,sizeof(used));
    for (int i=1;i<=N;i++)
        used[Map[1][i]]=true;
   
    for (int i=1;i<=P;i++)
    {
        if(used[i])
        {
            Abut[0]++;
            Mat[0][Abut[0]]=i;
            Val[0][Abut[0]]=Magic[i];
        }
    }
   
    memset(used,false,sizeof(used));
    for (int i=1;i<=N;i++)
        used[Map[N][i]]=true;
   
    for (int i=1;i<=P;i++)
    {
        if(used[i])
        {
            Abut[i]++;
            Mat[i][Abut[i]]=E;
            Val[i][Abut[i]]=0;
        }
    }
   
    return;
}

void CreatGraph()
{
    int nx,ny;
    int nc;
    for (int k=1;k<=P;k++)
    {
        for (int i=1;i<=N;i++)
        {
            for (int j=1;j<=N;j++)
            {
                if(Map[i][j]!=k)
                    continue;
                for (int m=0;m<4;m++)
                {
                    nx=i+step[m][0];
                    ny=j+step[m][1];
                    if(nx<1 || nx>N || ny<1 || ny>N)
                        continue;
                    nc=Map[nx][ny];
                    if(nc!=k && !used[k][nc] && nc!=-1)
                    {
                        Abut[k]++;
                        Mat[k][Abut[k]]=nc;
                        Val[k][Abut[k]]=Magic[nc];
                        used[k][nc]=true;
                       
                        Abut[nc]++;
                        Mat[nc][Abut[nc]]=k;
                        Val[nc][Abut[nc]]=Magic[k];
                        used[nc][k]=true;
                    }
                }
                Map[i][j]=-1;
            }
        }
    }
}

void Dijkstra(int S)
{
    for (int i=0;i<=E;i++)
    {
        dist[i]=MAX;
        flag[i]=false;
    }
    for(int i=1;i<=Abut[S];i++)
    {
        dist[Mat[S][i]]=Val[S][i];
    }
    dist[S]=0;
    flag[S]=1;
   
    for(int i=0;i<=E;i++)
    {
        int tmp=MAX;
        int u=S;
        for (int j=0;j<=E;j++)
        {
            if(!flag[j] && dist[j]<tmp)
            {
                u=j;
                tmp=dist[j];
            }
        }
        flag[u]=1;
       
        for (int j=0;j<=Abut[u];j++)
        {
            if(!flag[Mat[u][j]])
            {
                int newdist=dist[u]+Val[u][j];
                if(newdist<dist[Mat[u][j]])
                {
                    dist[Mat[u][j]]=newdist;
                }
            }
        }
    }
}

int main()
{
    freopen("eldrethalas.in","r",stdin);
    freopen("eldrethalas.out","w",stdout);
    init();
    CreatGraph();
    Dijkstra(0);
    int res=dist[E];
    if(res<H)
    {
        res=H-res;
        printf("%d\n",res);
    }
    else
        printf("NO\n");
    return 0;
}


【評測結果】
正在连接评测机...

已连接到评测机
GRID 1
名称 Flitty
系统版本 1.00
备注 COGS 1号评测机 Flitty
正在编译...
编译成功

测试点 结果 得分 运行时间 内存使用 退出代码
1 正确 10 0.000 s 55463 KB 0
2 正确 10 0.091 s 55463 KB 0
3 正确 10 0.000 s 55463 KB 0
4 正确 10 0.000 s 55463 KB 0
5 正确 10 0.001 s 55463 KB 0
6 正确 10 0.001 s 55463 KB 0
7 正确 10 0.019 s 55463 KB 0
8 正确 10 0.065 s 55463 KB 0
9 正确 10 0.080 s 55463 KB 0
10 正确 10 0.080 s 55463 KB 0
运行完成
运行时间 0.338 s
平均内存使用 55463 KB
测试点通过状况 AAAAAAAAAA
得分:100
恭喜你通过了全部测试点!

USACO Contest Nov2011 成績終於評出來了

等了好幾天,USACO Contest Nov2011的成績終於出來了。

我第一次參加USACO Contest,銅組的,成績還可以,950分,最後一題的最後兩組測試數據錯了,少判斷了一種情況,已經改對了。

我的同學Shijian Liu大牛,拿了1000分,NB啊!!


成績查看頁:http://www.usaco.org/current/data/nov11_bronze_prelim.html

 我的代碼已經在幾天前在我的blog裡發布了。

我剛剛把我第四題的代碼修改了一下,加了一行語句,然後自評,AC了。


成績:
CHN 2013 Yeefan Zhu 950

ctiming   **********
digits      **********
moosick  **********
pageant  ********xx

Key:
* = Correct
x = Wrong Answer
t = Timeout
c = Didn't Compile
s = Signal (crashed, exceeded memory limits, invalid syscall)












































































































2011年11月18日 星期五

[USACO Oct08 Gold] Power Failure 供電故障(pwrfail) 解題報告

【題目描述】
一場邪惡的暴風雨毀壞了農夫約翰的輸電網中的一些電綫!農夫約翰有一張包含了所有 n(2<=n<=1000)個電能中轉點的地圖,這些 點被很自然而方便的標識爲1..n,並且被整數座標x_i,y_i(-100000<=x_i<=100000;-100000& lt;=y_i<=100000)定位於座標系。
有w(1<=w<=10000)條電綫仍然保存着沒被暴風雨破壞,每條電綫連接着兩個電能中轉點pi,pj(1<=pi<=n;1<=pj<=n)。
他希望從第一個電能中轉點把電導入第n個(可能通過一些中間的電能中轉點,應當有一組電綫連接1和n)。
給出n個電能中轉點的座標和倖存的電綫,請確定最少需要架設的電綫總長度,但請注意,架設過程中,對於單條電綫而言,其長度不應超過m(0.0<=m<=200000.0)
給出一個例子,在下面,左邊是一個包含9個電能中轉電和3條倖存電綫的地圖。在這個任務中,規定名。m=2.0。最佳的架設方案是連接6和4,以及6和9。
   After the storm              Optimally reconnected
3  . . . 7 9 . . . . .          3  . . . 7 9 . . . . .
                                          /
2  . . 5 6 . . . . . .          2  . . 5 6 . . . . . .
                                        /
1  2-3-4 . 8 . . . . .          1  2-3-4 . 8 . . . . .
   |                               |
0  1 . . . . . . . . .          0  1 . . . . . . . . .

   0 1 2 3 4 5 6 7 8 9             0 1 2 3 4 5 6 7 8 9
這是的總長度是 1.414213562 + 1.414213562 = 2.828427124 .

題目名稱:pwrfail
輸入格式
  • 第一行:兩個用空格隔開的整數 n和w
  • 第二行:一個實數:m
  • 第3..n+2:每一行包含兩個用空格隔開的整數:x_i和y_i
  • 第n+3..n+2+w行:兩個空格隔開的整數:pi和pj
輸入樣例(file pwrfail):
9 3
2.0
0 0
0 1
1 1
2 1
2 2
3 2
3 3
4 1
4 3
1 2
2 3
3 4
輸入說明
就像圖表中說的那樣。
輸出格式
第一行:一個整數,實際結果乘以1000後取整。請不要進行任何的4舍5入工作。
輸出樣例(file pwrfail.out):
2828
 
【分析】 
明顯,這是求圖的最短路徑問題,由於N=1000,顯然Floyd算法會超時,
所以要用SPFA、Dijkstra等 O(n^2)算法。
構圖時要用勾股定理算出任意兩點間的距離,因為有M的限制,
所以可以用鄰接表進行優化。
 
注意:C++中要用double型,因為這是實數。
 
【我的代碼】(用鄰接矩陣寫的,有空的話再改成鄰接表吧)
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cmath>
using namespace std;
const double MAX=200000000;
const int MAXN=1001;
int N,W;
double M;
double Mat[MAXN][MAXN];
double dist[MAXN];
bool flag[MAXN];

class POING
{
public:
 int x,y;
}P[1001];

double GetDis(int a,int b)
{
 double tmp1,tmp2;
 tmp1=P[a].x-P[b].x;
 tmp2=P[a].y-P[b].y;
 double tmp=tmp1*tmp1+tmp2*tmp2;
 return sqrt(tmp);
}

void init()
{
 scanf("%d %d\n",&N,&W);
 scanf("%lf",&M);
 int a,b;
 for(int i=1;i<=N;i++)
  scanf("%d %d\n",&P[i].x,&P[i].y);
 
 for (int i=1;i<=N;i++)
 {
  for (int j=1;j<=N;j++)
  {
   Mat[i][j]=GetDis(i,j);
   if(Mat[i][j]>M)
    Mat[i][j]=MAX;
  }
 }
 
 for (int i=1;i<=W;i++)
 {
  scanf("%d %d\n",&a,&b);
  Mat[a][b]=0;
  Mat[b][a]=0;
 }
}

void Dijkstra(int S)
{
 for (int i=1;i<=N;i++)
 {
  dist[i]=Mat[S][i];
  flag[i]=false;
 }
 
 dist[S]=0;
 flag[S]=1;
 
 for (int i=2;i<=N;i++)
 {
  double tmp=MAX;
  int u=S;
  for (int j=1;j<=N;j++)
  {
   if(!flag[j] && dist[j]<tmp)
   {
    u=j;
    tmp=dist[j];
   }
  }
  flag[u]=1;
  
  for (int j=1; j<=N;j++)
  {
   if(!flag[j])
   {
    double newdist=dist[u]+Mat[u][j];
    if(newdist<dist[j])
    {
     dist[j]=newdist;
    }
   }
  }
 }
}

int main()
{
 freopen("pwrfail.in","r",stdin);
 freopen("pwrfail.out","w",stdout);
 init();
 Dijkstra(1);
 double tmp=dist[N];
 int ans;
 if(tmp==MAX)
  ans=-1;
 else
  ans=int(tmp*1000);
 printf("%d\n",ans);
 return 0;
} 
 
【評測結果】
正在连接评测机...

已连接到评测机
GRID 1
名称 Flitty
系统版本 1.00
备注 COGS 1号评测机 Flitty
正在编译...
编译成功

测试点 结果 得分 运行时间 内存使用 退出代码
1 正确 5 0.000 s 8116 KB 0
2 正确 5 0.004 s 8116 KB 0
3 正确 5 0.007 s 8116 KB 0
4 正确 5 0.012 s 8116 KB 0
5 正确 5 0.021 s 8116 KB 0
6 正确 5 0.026 s 8116 KB 0
7 正确 5 0.036 s 8116 KB 0
8 正确 5 0.041 s 8116 KB 0
9 正确 5 0.058 s 8116 KB 0
10 正确 5 0.072 s 8116 KB 0
11 正确 5 0.070 s 8116 KB 0
12 正确 5 0.000 s 8116 KB 0
13 正确 5 0.072 s 8116 KB 0
14 正确 5 0.000 s 8116 KB 0
15 正确 5 0.000 s 8116 KB 0
16 正确 5 0.000 s 8116 KB 0
17 正确 5 0.001 s 8116 KB 0
18 正确 5 0.001 s 8116 KB 0
19 正确 5 0.001 s 8116 KB 0
20 正确 5 0.001 s 8116 KB 0
运行完成
运行时间 0.426 s
平均内存使用 8116 KB
测试点通过状况 AAAAAAAAAAAAAAAAAAAA
得分:100
恭喜你通过了全部测试点!

USACO 1.4.4 Mother's Milk 母親的牛奶 解題報告

Mother's Milk
Farmer John has three milking buckets of capacity A, B, and C liters. Each of the numbers A, B, and C is an integer from 1 through 20, inclusive. Initially, buckets A and B are empty while bucket C is full of milk. Sometimes, FJ pours milk from one bucket to another until the second bucket is filled or the first bucket is empty. Once begun, a pour must be completed, of course. Being thrifty, no milk may be tossed out.
Write a program to help FJ determine what amounts of milk he can leave in bucket C when he begins with three buckets as above, pours milk among the buckets for a while, and then notes that bucket A is empty.

PROGRAM NAME: milk3

INPUT FORMAT

A single line with the three integers A, B, and C.

SAMPLE INPUT (file milk3.in)

8 9 10

OUTPUT FORMAT

A single line with a sorted list of all the possible amounts of milk that can be in bucket C when bucket A is empty.

SAMPLE OUTPUT (file milk3.out)

1 2 8 9 10

SAMPLE INPUT (file milk3.in)

2 5 10

SAMPLE OUTPUT (file milk3.out)

5 6 7 8 9 10
 
 
【中文翻譯】 
描述
農民約翰有三個容量分別是A,B,C升的桶,A,B,C分別是三個從1到20的整數,
最初,A和B桶都是空的,而C桶是裝滿牛奶的。有時,約翰把牛奶從一個桶倒到另一個桶中,直到被灌桶裝滿或原桶空了。當然每一次灌注都是完全的。由於節約,牛奶不會有丟失。
寫一個程序去幫助約翰找出當A桶是空的時候,C桶中牛奶所剩量的所有可能性。
格式
PROGRAM NAME: milk3
INPUT FORMAT:
(file milk3.in)
單獨的一行包括三個整數A,B和C。
OUTPUT FORMAT:
(file milk3.out)
只有一行,升序地列出當A桶是空的時候,C桶牛奶所剩量的所有可能性。
SAMPLE INPUT 1
8 9 10
SAMPLE OUTPUT 1
1 2 8 9 10
SAMPLE INPUT 2
2 5 10
SAMPLE OUTPUT 2
5 6 7 8 9 10
 
【分析】
 由於數據規模很小,可以用dfs+哈希判重。
遞歸函數有3個參數a,b,c,分別表示A、B、C這三個桶中牛奶的剩餘量。
一共有6種可能的移動方式:
1. A->B
2. A->C
3. B->A
4. B->C
5. C->A
6. C->B 
有一些顯而易見的減枝,如當一個桶的剩餘量大於0時才倒出等。 
 
可以開一個三維bool型數組用來判重。
 
當然,結果也可以用哈希數組來存儲。 
當a==0時記錄下這時c的值,最後從小到大輸出所有可能的c值即可。
 
【我的代碼】
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
bool flag[21][21][21];
int rs[21];
int A,B,C;


int Min(int a,int b)
{
 if(b<a)
  a=b;
 return a;
}

void init()
{
 scanf("%d %d %d\n",&A,&B,&C);
 for (int i=1;i<=C;i++)
  for(int j=1;j<=C;j++)
   for (int k=1;k<=C;k++)
    flag[i][j][k]=false;
 for (int i=1;i<=C;i++)
  rs[i]=false;
 return;
}

void dfs(int a,int b,int c)
{
 flag[a][b][c]=true;
 //cout<<a<<" "<<b<<" "<<c<<endl;
 
 if(a==0)
  rs[c]=true;
 
 int ta,tb,tc;
 if(a>0)
 {
  //a->b
  int t=Min(a,B-b);
  ta=a-t;
  tb=b+t;
  tc=c;
  if(!flag[ta][tb][tc])
   dfs(ta,tb,tc);
  
  //a->c
  t=Min(a,C-c);
  ta=a-t;
  tb=b;
  tc=c+t;
  if(!flag[ta][tb][tc])
   dfs(ta,tb,tc);
 }
  
 if(b>0)
 {
  //b->a
  int t=Min(b,A-a);
  ta=a+t;
  tb=b-t;
  tc=c; 
  if(!flag[ta][tb][tc])
   dfs(ta,tb,tc);
  
  //b->c
  t=Min(b,C-c);
  ta=a;
  tb=b-t;
  tc=c+t;
  if(!flag[ta][tb][tc])
   dfs(ta,tb,tc);
 }
 
 if(c>0)
 {
  //c->a
  int t=Min(c,A-a);
  ta=a+t;
  tb=b;
  tc=c-t;
  if(!flag[ta][tb][tc])
   dfs(ta,tb,tc);
  
  //c->b
  t=Min(c,B-b);
  ta=a;
  tb=b+t;
  tc=c-t;
  if(!flag[ta][tb][tc])
   dfs(ta,tb,tc);
 }
 
}

int main()
{
 freopen("milk3.in","r",stdin);
 freopen("milk3.out","w",stdout);
 init();
 dfs(0,0,C);
 for (int i=0;i<=C;i++)
  if(rs[i])
   cout<<i<<" ";
 return 0;
}
 
【評測結果】 
正在连接评测机...

已连接到评测机
GRID 1
名称 Flitty
系统版本 1.00
备注 COGS 1号评测机 Flitty
正在编译...
编译成功

测试点 结果 得分 运行时间 内存使用 退出代码
1 正确 10 0.000 s 281 KB 0
2 正确 10 0.000 s 281 KB 0
3 正确 10 0.000 s 281 KB 0
4 正确 10 0.000 s 281 KB 0
5 正确 10 0.000 s 281 KB 0
6 正确 10 0.000 s 281 KB 0
7 正确 10 0.000 s 281 KB 0
8 正确 10 0.000 s 281 KB 0
9 正确 10 0.000 s 281 KB 0
10 正确 10 0.000 s 281 KB 0
运行完成
运行时间 0.003 s
平均内存使用 281 KB
测试点通过状况 AAAAAAAAAA
得分:100
恭喜你通过了全部测试点!

2011年11月13日 星期日

USACO 2011 November Contest, Bronze Division Problem 4. Cow Beauty Pageant (pageant)

Problem 4: Cow Beauty Pageant (Bronze Level) [Brian Dean] 

Hearing that the latest fashion trend was cows with two spots on their hides, Farmer John has purchased an entire herd of two-spot cows. Unfortunately, fashion trends tend to change quickly, and the most popular current fashion is cows with only one spot! 

FJ wants to make his herd more fashionable by painting each of his cows in such a way that merges their two spots into one. The hide of a cow is represented by an N by M (1 <= N,M <= 50) grid of characters like this: 
................
..XXXX....XXX...
...XXXX....XX...
.XXXX......XXX.. 
........XXXXX...
.........XXX....

Here, each 'X' denotes part of a spot. Two 'X's belong to the same spot if they are vertically or horizontally adjacent (diagonally adjacent does not count), so the figure above has exactly two spots.
 All of the cows in FJ's herd have exactly two spots.

FJ wants to use as little paint as possible to merge the two spots into one. In the example above, he can do this by painting only three additional characters with 'X's (the new characters are marked with '*'s below to make them easier to see). 
................ 
..XXXX....XXX...
...XXXX*...XX...
.XXXX..**..XXX..
........XXXXX... 
.........XXX.... 

Please help FJ determine the minimum number of new 'X's he must paint in order to merge two spots into one large spot. 

PROBLEM NAME: pageant 

INPUT FORMAT: 
* Line 1: Two space-separated integers, N and M.
* Lines 2..1+N: Each line contains a length-M string of 'X's and '.'s specifying one row of the cow hide pattern.

SAMPLE INPUT (file pageant.in): 
6 16 
................
..XXXX....XXX... 
...XXXX....XX...
.XXXX......XXX..
........XXXXX...
.........XXX....

INPUT DETAILS: 
The pattern in the input shows a cow hide with two distinct spots, labeled 1 and 2 below: 
................
..1111....222... 
...1111....22... 
.1111......222..
........22222...
.........222.... 

OUTPUT FORMAT: 
* Line 1: The minimum number of new 'X's that must be added to the input pattern in order to obtain one single spot.

SAMPLE OUTPUT (file pageant.out): 


OUTPUT DETAILS:
Three 'X's suffice to join the two spots into one:
................ 
..1111....222...
...1111X...22... 
.1111..XX..222..
........22222...
.........222....

【分析】
Floodfill,可以使用廣度優先搜索。
枚舉spot1內的所有點 與 spot2內的所有點,找出兩個 橫坐標相減的絕對值與橫坐標相減的絕對值之和再減一 的最小值,輸出這個值即可。

【我的代碼(這是我改後的程序,自測AC滿分)】
/*
ID:zyfwork1
PROB:pageant
LANG:C++
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
int N,M;
int Mat[51][51];

int step[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int One[2600][2];
int Two[2600][2];
int topa=0;
int topb=0;

int abs(int a)
{
    return a>0?a:-a;
}

void init()
{
    scanf("%d %d\n",&N,&M);
    char c;
    for (int i=1;i<=N;i++)
    {
        for (int j=1;j<=M;j++)
        {
            cin>>c;
            if(c=='.')
                Mat[i][j]=0;
            if(c=='X')
                Mat[i][j]=-1;
        }
    }
}

void bfs(int n)
{
    int Q[2600][2];
    int big=1;
    int sma=0;
    for (int i=1;i<=N;i++)
    {
        bool flag=false;
        for(int j=1;j<=M;j++)
        {
            if(Mat[i][j]==-1)
            {
                Q[0][0]=i;
                Q[0][1]=j;
                flag=true;
                break;
            }
        }
        if(flag)
            break;
    }
   
    int x,y;
    int tx,ty;
    while(sma<big)
    {
        x=Q[sma][0];
        y=Q[sma][1];
        Mat[x][y]=n;


        if(n==1)
        {
            topa++;
            One[topa][0]=x;
            One[topa][1]=y;
        }
        if(n==2)
        {
            topb++;
            Two[topb][0]=x;
            Two[topb][1]=y;
        }
       
        for (int i=0;i<4;i++)
        {
            tx=x+step[i][0];
            ty=y+step[i][1];
            if(tx>=1 && tx<=N && ty>=1 && ty<=M)
            {
                if(Mat[tx][ty]!=-1)
                    continue;
                Q[big][0]=tx;
                Q[big][1]=ty;
                Mat[tx][ty]=n;
                big++;
            }
        }
        sma++;
    }
}

int main()
{
    freopen("pageant.in","r",stdin);
    freopen("pageant.out","w",stdout);
    init();
    bfs(1);
    bfs(2);
    int ans=0x7fffffff;
    for (int i=1;i<=topa;i++)
    {
        int x=One[i][0];
        int y=One[i][1];
        for (int j=1;j<=topb;j++)
        {
            int xx=Two[j][0];
            int yy=Two[j][1];
            int tmp=abs(xx-x)+abs(yy-y);
            if( tmp<ans )
                ans=tmp;
        }
    }
    printf("%d\n",ans-1);
    return 0;
}

USACO 2011 November Contest, Bronze Division Problem 3. Moo Sick (moosick)

Problem 3: Moo Sick [Rob Seay]

Everyone knows that cows love to listen to all forms of music. Almost all forms, that is -- the great cow composer Wolfgang Amadeus Moozart once discovered that a specific chord tends to make cows rather ill. This chord, known as the ruminant seventh chord, is therefore typically avoided in all cow musical compositions. 

Farmer John, not knowing the finer points of cow musical history, decides to play his favorite song over the loudspeakers in the barn. Your task is to identify all the ruminant seventh chords in this song, to estimate how sick it will make the cows. 

The song played by FJ is a series of N (1 <= N <= 20,000) notes, each an integer in the range 1..88. A ruminant seventh chord is specified by a sequence of C (1 <= C <= 10) distinct notes, also integers in the range 1..88. However, even if these notes are transposed (increased or decreased by a common amount), or re-ordered, the chord remains a ruminant seventh chord! For example, if "4 6 7" is a ruminant seventh chord, then "3 5 6" (transposed by -1), "6 8 9" (transposed by +2), "6 4 7" (re-ordered), and "5 3 6" (transposed and re-ordered) are also ruminant seventh chords.

A ruminant seventh chord is a sequence of C consecutive notes satisfying the above criteria. It is therefore uniquely determined by its starting location in the song. Please determine the indices of the starting locations of all of the ruminant seventh chords. 

PROBLEM NAME: moosick

INPUT FORMAT: 
* Line 1: A single integer: N.
* Lines 2..1+N: The N notes in FJ's song, one note per line. 
* Line 2+N: A single integer: C.
* Lines 3+N..2+N+C: The C notes in an example of a ruminant seventh chord. All transpositions and/or re-orderings of these notes are also ruminant seventh chords.

SAMPLE INPUT (file moosick.in): 






10 
3


7

INPUT DETAILS: 
FJ's song is 1,8,5,7,9,10. A ruminant seventh chord is some transposition/re-ordering of 4,6,7. OUTPUT FORMAT:
* Line 1: A count, K, of the number of ruminant seventh chords that appear in FJ's song. Observe that different instances of ruminant seventh chords can overlap each-other.
* Lines 2..1+K: Each line specifies the starting index of a ruminant seventh chord (index 1 is the first note in FJ's song, index N is the last). Indices should be listed in increasing sorted order. 

SAMPLE OUTPUT (file moosick.out): 




OUTPUT DETAILS: Two ruminant seventh chords appear in FJ's song (and these occurrences actually overlap by one note). The first is 8,5,7 (transposed by +1 and reordered) starting at index 2, and the second is 7,9,10 (transposed by +3) starting at index 4.

【分析】
還是模擬題,先對那C個ruminant seventh chords進行排序,然後一次次的快速排序,判斷即可。

【我的代碼(成績出來了,滿分)】
/*
ID:zyfwork1
PROB:moosick
LANG:C++
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
int N,C;
int Num[20001];
int Sev[11];
int res[20001];
int top=0;

int cmp(const void  *a,const void  *b)
{
    return *((int *)a)-*((int *)b);
}

void init()
{
    scanf("%d",&N);
    for (int i=1;i<=N;i++)
        scanf("%d\n",&Num[i]);
    scanf("%d",&C);
    for (int i=1;i<=C;i++)
        scanf("%d\n",&Sev[i]);
    qsort(Sev+1,C,sizeof(Sev[0]),cmp);
    return;
}

void work()
{
    for (int i=1;i<=N-C+1;i++)
    {
        int tmp[11];
        memset(tmp,0,sizeof(tmp));
        int tt=1;
        for (int j=i;tt<=C;j++)
            tmp[tt++]=Num[j];
        qsort(tmp+1,C,sizeof(tmp[0]),cmp);
        int delta=tmp[1]-Sev[1];
       
        bool flag=true;
        for(int k=2;k<=C;k++)
        {
            if(tmp[k]-delta!=Sev[k])
            {
                flag=false;
                break;
            }
        }
        if(flag)
        {
            res[++top]=i;
        }
    }
   
    printf("%d\n",top);
    for (int i=1;i<=top;i++)
        printf("%d\n",res[i]);
   
}

int main()
{
    freopen("moosick.in","r",stdin);
    freopen("moosick.out","w",stdout);
    init();
    work();
    return 0;
}

USACO 2011 November Contest, Bronze Division Problem 2. Awkward Digits (digits)

Problem 2: Awkward Digits [Brian Dean]
Bessie the cow is just learning how to convert numbers between different bases, but she keeps making errors since she cannot easily hold a pen between her two front hooves.

Whenever Bessie converts a number to a new base and writes down the result, she always writes one of the digits wrong. For example, if she converts the number 14 into binary (i.e., base 2), the correct result should be "1110", but she might instead write down "0110" or "1111". Bessie never accidentally adds or deletes digits, so she might write down a number with a leading digit of "0" if this is the digit she gets wrong. 

Given Bessie's output when converting a number N into base 2 and base 3, please determine the correct original value of N (in base 10). You can assume N is at most 1 billion, and that there is a unique solution for N.

Please feel welcome to consult any on-line reference you wish regarding base-2 and base-3 numbers, if these concepts are new to you. 

PROBLEM NAME: digits 

INPUT FORMAT: * Line 1: The base-2 representation of N, with one digit written incorrectly. * Line 2: The base-3 representation of N, with one digit written incorrectly.

SAMPLE INPUT (file digits.in): 
1010
212 

INPUT DETAILS: When Bessie incorrectly converts N into base 2, she writes down "1010". When she incorrectly converts N into base 3, she writes down "212". 

OUTPUT FORMAT: * Line 1: The correct value of N. SAMPLE OUTPUT (file digits.out): 14 

OUTPUT DETAILS: The correct value of N is 14 ("1110" in base 2, "112" in base 3).

【分析】
暴力枚舉 二進制表示的每一位,然後轉換為10進制,再轉換成3進制,如果與給的3進制數只有1位相同,輸出這個數的10進制即可。

【我的代碼(成績出來了,滿分)
/*
ID:zyfwork1
PROB:digits
LANG:C++
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

int binary[100];
int nilen;
int san[100];
int sanlen;
int Tmp[100];
int tmplen;
int tmp[100];

int sq(int n,int base)
{
    int rs=1;
    for (int i=1;i<=base;i++)
        rs*=n;
    return rs;
}

int convert(int base,int len)
{
    int rs=0;
    int tl=len;
    len--;
    for (int i=1;i<=tl;i++)
    {
        rs+=tmp[i]*sq(2,len);
        len--;
    }
    return rs;
}

void init()
{
    char str[100];
    memset(str,'\0',sizeof(str));
    scanf("%s\n",&str);
    nilen=strlen(str);
    for (int i=1;i<=nilen;i++)
        binary[i]=str[i-1]-'0';
   
    memset(str,'\0',sizeof(str));
    scanf("%s\n",&str);
    sanlen=strlen(str);
    for (int i=1;i<=sanlen;i++)
        san[i]=str[i-1]-'0';
}

void Con(long long num)
{
    int Temp[100];
    memset(Temp,0,sizeof(Temp));
    int p=0;
    while(num)
    {
        Temp[++p]=num%3;
        num/=3;
    }
    tmplen=p;
    for (int i=1;i<=p;i++)
        Tmp[p-i+1]=Temp[i];
    return;
}

int main()
{
    freopen("digits.in","r",stdin);
    freopen("digits.out","w",stdout);
    init();
    for (int i=1;i<=nilen;i++)
    {
        memset(tmp,0,sizeof(tmp));
        for (int j=1;j<=nilen;j++)
            tmp[j]=binary[j];
        tmp[i]=!tmp[i];
        long long ten=convert(2,nilen);
        Con(ten);
       
        int error=0;
        if(sanlen!=tmplen)
            continue;
        for (int i=1;i<=sanlen;i++)
            if(Tmp[i]!=san[i])
                error++;
        if(error==1)
        {
            cout<<ten<<endl;
            break;
        }           
    }
    return 0;
}

USACO 2011 November Contest, Bronze Division Problem 1. Contest Timing (ctiming)

【題目描述】
Problem 1: Contest Timing [Brian Dean]
Bessie the cow is getting bored of the milk production industry, and
wants to switch to an exciting new career in computing. To improve her coding skills, she decides to compete in the on-line USACO
competitions. Since she notes that the contest starts on November 11, 2011 (11/11/11), she decides for fun to download the problems and begin coding at exactly 11:11 AM on 11/11/11.

 Unfortunately, Bessie's time management ability is quite poor, so she wants to write a quick program to help her make sure she does not take longer than the 3 hour (180 minute) time limit for the contest. Given the date and time she stops working, please help Bessie compute the total number of minutes she will have spent on the contest.

PROBLEM NAME: ctiming

INPUT FORMAT: * Line 1: This line contains 3 space-separated integers, D H M, specifying the date and time at which Bessie ends the contest. D will be an integer in the range 11..14 telling the day of the month; H and M are hours and minutes on a 24-hour clock (so they range from H=0,M=0 at midnight up through H=23,M=59 at 11:59 PM).

SAMPLE INPUT (file ctiming.in): 12 13 14

INPUT DETAILS: Bessie ends the contest on November 12, at 13:14 (that is, at 1:14 PM).

 OUTPUT FORMAT: * Line 1: The total number of minutes spent by Bessie in the contest, or -1 if her ending time is earlier than her starting time.

SAMPLE OUTPUT (file ctiming.out): 1563

OUTPUT DETAILS: Bessie ends the contest 1563 minutes after she starts.

【分析】
水題,直接模擬即可。

【我的代碼(成績出來了,滿分)
/*
ID:zyfwork1
PROB:ctiming
LANG:C++
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
int D,H,M;
int Start;
const int Day=1440;
const int Hour=60;

int GetMin(int d,int h,int m)
{
    int day=(d-1)*Day;
    int hour=h*Hour;
    int rs=day+hour+m;
    return rs;
}

int main()
{
    freopen("ctiming.in","r",stdin);
    freopen("ctiming.out","w",stdout);
    Start=GetMin(11,11,11);
    int a,b,c;
    cin>>a>>b>>c;
    int End=GetMin(a,b,c);
    int re=End-Start;
    if(re<0)
        cout<<-1<<endl;
    else
        cout<<re<<endl;
    return 0;
}