申請SAE

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

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

2011年12月10日 星期六

USACO Dec2011 Bronze: Escaping the Farm 翻譯+題解

Problem 3: Escaping the Farm [Brian Dean and Kalki Seksaria, 2011]
【英文原題】
The cows have decided on a daring plan to escape from the clutches of
Farmer John. They have managed to procure a small inflatable raft, and
during the cover of night, a group of cows will board the raft and row
across the river bordering the farm. The plan seems perfect, until the
cows realize that their small inflatable raft may not be able to hold
much weight!
The N cows (1 group of cows is light enough to avoid sinking the raft, the cows add up
all of the weights in the group. Unfortunately, cows are notoriously bad at
arithmetic, and if the addition of the weights of the cows in a group
causes any carries to occur (using standard base 10 addition), then the
cows give up and conclude that group must weigh too much to use the raft.
Any group whose weights can be added without any carries is assumed to be
light enough to fit on the raft.
Please help the cows determine the size of the largest group that they
believe can fit on the raft (that is, the largest group whose weights can
be added together with no carries).
PROBLEM NAME: escape
INPUT FORMAT:
* Line 1: The number of cows, N (1
* Lines 2..N+1: Each line contains the weight of one cow, an integer
in the range 1…100,000,000.
SAMPLE INPUT (file escape.in):
5
522
6
84
7311
19
INPUT DETAILS:
There are 5 cows, with weights 522, 6, 84, 7311, and 19.
OUTPUT FORMAT:
* Line 1: The number of cows in the largest group whose weights can be
added together with no carries.
SAMPLE OUTPUT (file escape.out):
3
OUTPUT DETAILS:
The three weights 522, 6, and 7311, can be added together with no carries:
522
6
+ 7311
——
7839

【中文翻譯】
Problem 3:逃離農場
譯by Freddy
【題目描述】
奶牛們做了一個魯莽的計劃:那就是逃離農場主Farmer John。她們已經獲得了一個可充氣的小型木筏,計劃在某天夜晚中,一群奶牛通過使用木筏渡而過位於農場邊界的河流。這個計劃似乎很完美,直到奶牛們意識到她們的小木筏可能不能承受住她們的體重。

這N頭奶牛(1<=N<=20)的體重w_1…w_N。為了計算出一群奶牛的體重能否避免木筏沉沒的悲劇,一群奶牛把她們的體重加在一起。
不幸的是,奶牛們在算術方面臭名遠揚,並且一群奶牛內的各奶牛體重相加的過程中如果出現了進位(標準的10進制),那麼這群奶牛只好放棄因為她們知道她們的體重對於小木筏來說太重了。

所有 那些群內奶牛體重相加不出現進位的奶牛群都被認為可以乘坐那個木筏而不發生沉沒。

請幫奶牛們找出能乘坐木筏而不沉沒的奶牛群的最大奶牛數。(也就是說,找出最多的奶牛使她們的體重相加而不出現進位。)

程序名:escape
輸入格式:
▪第1行:奶牛的數量,N(1<=N<=20)
▪第2…N+1行:每行包含一頭奶牛的體重,一個整數(1…100,000,000)。
輸入樣例(file escape.in):
5
522
6
84
7311
19
輸入解釋:
有5只奶牛,她們的體重分別為522,6,84,7311和19。
輸出格式:
只有一行,表示一群使她們的體重相加而不出現進位的奶牛的最大奶牛數量。
輸出樣例(file escape.out):
3
輸出解釋:



這三個奶牛的體重分別為:522,6,7311,它們相加不會出現進位:
    522
       6
+7311
 ——–
  7839

【分析】
搜索題目,可以用DFS。遞歸每頭牛的兩種狀態:要或者不要,每次遞歸判斷一下是否符合要求(沒有進位),然後更新最優值即可。
時間複雜度:
DFS遞歸:O(2^N)
判斷:O(KN) 『K是讀入的數字的平均長度,根據題意,可取5~6』

【我的代碼】
/*
ID:yeefan
LANG:C++
PROB:escape
website:http://yeefan.tk/
*/
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
int N;
int W[21];
int A=0;
int Q[21];
int Best=0;
void init()
{
 scanf("%d\n",&N);
 for (int i=1;i<=N;i++)
  scanf("%d\n",&W[i]);
 return;
}
void check()
{
 int T[11];
 memset(T,0,sizeof(T));
 for(int i=1;i<=A;i++)
 {
  int K=1;
  int tmp=W[Q[i]];
  while(tmp!=0)
  {
   T[K]+=tmp%10;
   tmp/=10;
   K++;
  }
 }
 for(int i=1;i<=10;i++)
 {
  if(T[i]>=10)
   return;
 }
 if(A>Best)
  Best=A;
}
void dfs(int num)
{
 if(num==N+1)
 {
  check();
  return;
 }
 Q[++A]=num;
 dfs(num+1);
 A--;
 dfs(num+1);
}
int main()
{
 freopen("escape.in","r",stdin);
 freopen("escape.out","w",stdout);
 init();
 dfs(1);
 printf("%d\n",Best);
 //printf("%d\n",clock());
 return 0;
}

2011年12月8日 星期四

【精華轉載】因為我們是OIer!

我們是OIer,

所以我們
不用在跑道上揮汗如雨;
不用在球場上健步如飛;
更不用在沒事的時候,
經受非人的體能訓練……
但是,
我們卻要把頭腦
高速運轉,
還要接受一大堆
大學生也只是
“瞭解即可”的知識,
把一個個抽象的問題
轉化為一篇篇
優美的代碼,
才能在F9按下以後
獲得歡呼。
不要以為我們
機房裡沒有風吹,
沒有日曬,
就比勤勞的體育生們輕鬆,
只不過是大腦和四肢
的區別罷了。
可是,
OIer的寂寞和委屈又有誰能懂?
自習課鏖戰機房,
卻被認為而是逃課上網;
為榮耀耽誤考試去比賽,
卻被認為是逃避。
體育的同學們雖然辛苦,
但在揮汗如雨的背後,
有人在喝彩鼓掌;
在風吹日曬的同時,
有粉絲在仰慕。
而我們呢?
與UnAC較勁的時候,
只有那一遍遍的運行窗口,
知道我們的不屈;
刷題的漫漫長夜,
只有陪伴我們的筆記本電腦,
知道我們的不懈;
在自習課別人學習的時候,
只有板磚般的算法導論,
知道我們的進取;
在機房泡得搶不上飯的時候,
只有五毛一包的乾脆面,
知道我們的執著……
沒有人會理解,
OIer見面,
除了程序、算法之外
別無他言。
我們的世界裡,
從來不會有遊戲、歌星的出現。
這不是被家長逼迫的“小三門”,
是我們的興趣,
我們的愛好,
乃至我們的事業。
每一個OIer都幻想著
自己脖子上可以
掛上一塊沉甸甸的金牌,
而不是
萬惡的應試教育的枷鎖。
沒準哪個OIer,
就是下一個艾倫•圖靈,
挑戰頭腦的極限,
去做最不平凡的自己。。。。。。

【精華轉載】假如沒有OI

假如沒有OI,我會像其他大多數人一樣擡頭看天,低頭看書,安靜的過完整個高中
假如沒有OI,我會一個人,一邊寫著作業,一邊做著肥皂般繁華的夢
假如沒有OI,我會輕鬆地擠進學校前100名,然後衣食無憂地等著高考地到來
假如沒有OI,我可以只用一半自習課的時間寫完所有作業,而不是晚上熬到深夜
假如沒有OI,我從來都不會知道矩陣,行列式,容斥原理等原本不屬於我們這個年齡的東西
假如沒有OI,我會花錢買一本《人間詞話》,而不是板磚一樣的《C++ primer》
假如沒有OI,我的空間裡會有一篇篇自己寫的詩或散文,而不是一堆解題報告
假如沒有OI,我永遠也不會聽說OIER這個名詞,也永遠不會去RQNOJ,BYVoid等網站
假如沒有OI,我在學校最常去的地方是圖書館,而不是機房
假如沒有OI,我的電腦裡會塞滿遊戲,而不是裝著IDE,編譯器和一包包的測試資料
假如沒有OI,我每天都會有大把的時間可以去放肆地揮霍
假如沒有OI,我永遠也不知道”犇“的讀音
假如沒有OI,我可能不會知道夢的含義,還有什麼是拼搏
假如沒有OI,我可能會和同學們一樣,週末去網吧聯機dota
假如沒有OI,我以後可能永遠也接觸不到演算法和編程
假如沒有OI,我會像所有的普通人一樣,平平淡淡,終其一生

NOIP2011提高組 Day2 計算係數 factor 解題報告

題目查看、下載

【題目分析】
數論,C(k,m)*a^n*b^m即可。C(k,m)表示組合數,可以使用楊輝三角遞推求出。
考察知識點:
1) 二項式定理
2) 組合數遞推/楊輝三角
3) 同餘定理


【我的代碼】

#include <cstdio>
#include <iostream>
#include <cstdlib>
using namespace std;
int A,B,K,N,M;
const int MOD=10007;
int YH[1020][1020];
void yanghui()
{
 for (int i=0;i<=K+1;i++)
  for (int j=1;j<=K+2;j++)
   YH[i][j]=0;
 for (int i=0;i<=K+1;i++)
  YH[i][1]=1;
 for (int i=1;i<=K;i++)
 {
  for (int j=2;j<=i+1;j++)
  {
   YH[i][j]=(YH[i-1][j-1]+YH[i-1][j])%MOD;
  }
 }  
 
 /*
 for (int i=0;i<=K;i++)
 {
  for (int j=1;j<=i+1;j++)
   printf("%d ",YH[i][j]);
  printf("\n");
 }
 */
}
 
int Get(int num,int index)
{
 int res=1;
 for (int i=1;i<=index;i++)
  res=(res*num)%MOD;
 return res;
}
 
int main()
{
 freopen("factor.in","r",stdin);
 freopen("factor.out","w",stdout);
 scanf("%d %d %d %d %d\n",&A,&B,&K,&N,&M);
 yanghui();
 int NM=Get(A%MOD,N);
 int MM=Get(B%MOD,M);
 int res=(NM*MM)%MOD;
 res=(res*YH[K][M+1])%MOD;
 //printf("%d %d\n",NM,MM);
 printf("%d\n",res);
 return 0;
}

2011年12月6日 星期二

【BFS】GZOI2011廣州2011選拔賽:理財年代 money 解題報告

【問題描述】
最近通貨膨脹很厲害,CPI跑得比銀行利息要快,要抗通脹,又要避風險,其中一種很好的方式,就是購買銀行發行的理財產品。雖然理財產品的利息比銀行定期要高,而且沒有風險,但是,購買理財產品需要一定的資金門檻,而且還要保證吧錢存入一定時間不能取出來,因此也是有一定的限制的。
小郭很喜歡研究銀行的理財產品,她計劃在2011年拿10萬元進行理財產品的投資,為了簡單方便,她在2011年每次投資理財產品時,都是把這筆資金和之前購買理財產品產生的所有利息投入進去,希望在年底獲取最高的利潤。
【理財產品】
一個理財產品有如下要素:
資金門檻:至少要投入多少資金;
發行時間:該理財產品的購買時間;
投資天數:資金存放的天數,
年利息:該理財產品如果存放一年365天能獲取的利息。
由於郭小姐選擇的所有理財產品的門檻都是10萬以內,因此理財產品就剩下的3個要素。
例如,A1理財產品,發行時間是3月1日,投資天數為30天,年利息為 3.5%,那麼,如果10萬元購買該產品,那麼在30天后,也就是3月30日收市後,她可以獲得的資金為:
`100000*(1+0.035*30/365)=100287.67元 (四捨五入,保留2位小數)
然後,她就可以吧100287.67元這筆資金,購買3月31日或之後發行的任何理財產品。
郭小姐在這一年內不斷把本金和利息一起全額地購買理財產品,希望在2012年到來之前獲得最高的收益。如果購買的兩個理財產品之間有時間間隔,那麼這筆錢就不能產生利潤(銀行活期利息太低,利潤可以忽略)。請問她這年內,能通過購買理財產品,最多獲取多少錢呢?
【輸入格式】
第一行是整數N(1<=N<=15),代表理財產品的數目
下面N行為3個由空格隔開的字元串 A B C
A代表發行時間,格式為MMDD(兩位月兩位日),例如4月1日則為0401,10月2日則為1002
B (整數),代表投資天數,範圍是[10,300]
C (最多2位的小數),代表百分之幾的年利息,範圍是[3,30]
輸入資料保證 發行時間+投資天數不會超過2012年。
【輸出格式】
輸出只有一行,為年底最多可獲得的連本帶利的資金數目,保留2位小數
【輸入樣例】
3
0101 100 4.5
0201 30 5
0402 50 7.8
【例子分析】
例子中的3個理財產品,只能購買1號產品,或者連續購買2號、3號理財產品。
購買1號理財產品的收益為 100000*(1+0.045*100/365)=101232.88
購買2/3號理財產品的收益為:
購買2號產品後總資金: 100000*(1+0.05*30/365)=100410.96
再購買3號產品後總資金: 100410.96*(1+0.078*50/365)=101483.84
因此最高收益為 101483.84
【輸出樣例】
101483.84

【分析】
本題是廣州NOI選拔賽中比較簡單的一道,可以用BFS廣度優先搜索做。由於N很小、而且減枝十分有效,所以隊列會很小。
本題易錯地方有:
1) 日期的轉換和判斷
2) 利息的計算

【我的代碼】
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
int N;
class Money
{
public:
    int Mon;
    int Days;
    int Day1;
    int Day2;
    int Time;
    double Rate;
}M[30];

int days(int b,int c) 

    int d=0; 
    if(b==1) d=c; 
    if(b==2) d=31+c; 
    if(b==3) d=60+c; 
    if(b==4) d=91+c; 
    if(b==5) d=121+c; 
    if(b==6) d=152+c; 
    if(b==7) d=182+c; 
    if(b==8) d=213+c; 
    if(b==9) d=244+c; 
    if(b==10) d=274+c; 
    if(b==11) d=305+c; 
    if(b==12) d=335+c; 
    return d; 


int cmp(const void *a,const void *b)
{
    class Money *c=(class Money *)a;
    class Money *d=(class Money *)b;
    if(c->Day1!=d->Day1)
        return c->Day1-d->Day1;
    return c->Day2-d->Day2;
}

void init()
{
    scanf("%d\n",&N);
    int tmp1,tmp2;
    char ch1,ch2;
    for (int i=1;i<=N;i++)
    {
        scanf("%c%c",&ch1,&ch2);
        tmp1=(ch1-'0')*10+ch2-'0';
        scanf("%c%c",&ch1,&ch2);
        tmp2=(ch1-'0')*10+ch2-'0';
        M[i].Mon=tmp1;
        M[i].Days=tmp2;
        M[i].Day1=days(tmp1,tmp2);
        scanf("%d %lf\n",&M[i].Time,&M[i].Rate);
        M[i].Day2=M[i].Day1+M[i].Time-1;
    }
    qsort(M+1,N,sizeof(M[0]),cmp);
}

class QUEUE
{
public:
    double money;
    int pos;
    int day;
}Q[100000];

double GetMoney(double ben,int num)
{
    double res=ben;
    double rate=double(1)+M[num].Rate*(double(M[num].Time)/double(365))/(double(100));
    res=res*rate;
    return res;
}

void bfs()
{
    double S=0;
    int head=N;
    int rear=0;
    for (int i=1;i<=N;i++)
    {
        Q[i-1].pos=i;
        Q[i-1].money=GetMoney(double(100000),i);
        Q[i-1].day=M[i].Day2+1;
    }
   
    double tm;
    int td;
    int tp;
    while(rear<head)
    {
        tm=Q[rear].money;
       
        if(tm>S)
            S=tm;
       
        td=Q[rear].day;
        tp=Q[rear].pos;
        for(int i=tp+1;i<=N;i++)
        {
            if(M[i].Day1>=td)
            {
                Q[head].money=GetMoney(tm,i);
                Q[head].pos=i;
                Q[head].day=M[i].Day2+1;
                head++;
            }
        }
        rear++;
    }
    printf("%.2lf\n",S);
}


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