1. 程式人生 > >第八屆程式設計競賽-題目分析

第八屆程式設計競賽-題目分析

出題人:lrj

The Eighth Hunan Collegiate Programming Contest

HN第八屆大學生程式設計競賽        2012 /10/12 AM9:00-14:00
                                                                             考點                                 難度                       
題目A. 三家人                                                     計算題                                
 ☆
題目B. 機器人的指令                                          簡單模擬                               
Problem C. Updating a Dictionary                    字串處理                             
題目D. 平方根大搜索                                       二分求開方+高精度 
題目E. 最短的名字                                           trie 樹 統計字元                      

Problem F. Kingdoms              
題目G. 網格中的三角形                                    計算幾何                                
Problem H. Tin Cutter II
Problem I. Collecting Coins                          
題目J. 病毒                                                        LCIS                                     

Problem K. Cross-Shaped Tests                  
題目L. 安全區域                                                3D計算幾何 


下面給出部分題目的解答:

題目A. 三家人

有點像腦筋急轉彎!

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int main()
{
    int T;
    cin>>T;
    double a,b,money;
    while(T--)
    {
        cin>>a>>b>>money;
        double single=(a+b)/3;//每個人自己的那份
        double ans=money*(a-single)/single;
       printf("%.0lf\n",ans);//注意四捨五入
    }
    return 0;
}
題目B. 機器人的指令
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int main()
{
    int i,j,n,T;
    cin>>T;
    char s[100];
    int a[102];
    int pos;
    while(T--)
    {
        pos=0;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%s",s);
            if(s[0]=='L')
            {
                pos--;
                a[i]=-1;
            }
            else if(s[0]=='R')
            {
                pos++;
                a[i]=1;
            }
            else
            {
                scanf("%s",s);
                scanf("%d",&j);
                a[i]=a[j];
                pos+=a[i];
            }
        }
        printf("%d\n",pos);
    }
    return 0;
}
Problem C. Updating a Dictionary 
這題因為題目中說了一定存在空字典這裡wa了2次
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <stack>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
using namespace std;
#define LL long long
#define M 105
#define DEBUG puts("It's here!")
#define INF 1<<29
#define kind 30
#define CLS(x,v) memset(x,v,sizeof(x))
#define FOR(i,a,n)  for(int i=(a);i<=(n);++i)


map<string,string> m;
set<string> add,del,update;
char a[102];
void init()
{
    m.clear();
    add.clear();
    del.clear();
    update.clear();
}
void split()
{
    int i=1;
    int len=strlen(a)-1;//去除右括號
    string key,val;
    while(i<len)
    {
        key="";val="";
        while(i<len&&a[i]!=':'){ key+=a[i];i++;}
        i++;
        while(i<len&&a[i]!=','){ val+=a[i];i++;}
        i++;
        if(key.length()>0)
            m.insert(make_pair<string, string>(key, val));
    }
}
void solve()
{
    int i=1;
    int len=strlen(a)-1;//去除右括號
    string key,val;
    map<string,string>::iterator it;
    while(i<len)
    {
        key="";val="";
        while(i<len&&a[i]!=':'){ key+=a[i];i++;}
        i++;
        while(i<len&&a[i]!=','){ val+=a[i];i++;}
        i++;
        if(key.length()>0)
        {
            it=m.find(key);
            if(it==m.end())
            { // 原來的字典中不存在
                add.insert(key);
            }
            else //原來的字典中存在
            {  
                if(it->second!=val) //value改變
                    update.insert(key);
                 m.erase(it);//del
            }
        }
    }
}
void show(set<string>& out)
{
    set<string>::iterator it=out.begin();
    printf("%s",(*it).c_str());
    for(++it;it!=out.end();++it)
       printf(",%s",(*it).c_str());
    printf("\n");
}
void output()
{
    int flag=1;
    if(add.size()>0){flag=0;printf("+");show(add);}
    if(del.size()>0){flag=0;printf("-");show(del);}
    if(update.size()>0){flag=0;printf("*");show(update);}
    if(flag)printf("No changes\n");
    printf("\n");
}
int main()
{
    int T;
     //freopen("in.txt","r",stdin);
    scanf("%d",&T);
    while(T--)
    {
        init();
        scanf("%s",a);
        split();
        scanf("%s",a);
        solve();
        map<string,string>::iterator  it;
        for(it=m.begin(); it!=m.end(); it++)
                del.insert(it->first);
        output();
    }
    return 0;
}

題目E. 最短的名字

        在一個奇怪的村子中,很多人的名字都很長,比如aaaaa, bbb and abababab。
名字這麼長,叫全名顯然起來很不方便。所以村民之間一般只叫名字的字首。比如叫'aaaaa'的
時候可以只叫'aaa',因為沒有第二個人名字的前三個字母是'aaa'。不過你不能叫'a',因為有兩
個人的名字都以'a'開頭。村裡的人都很聰明,他們總是用最短的稱呼叫人。輸入保證村裡不會
有一個人的名字是另外一個人名字的字首(作為推論,任意兩個人的名字都不會相同)。
如果村裡的某個人要叫所有人的名字(包括他自己),他一共會說多少個字母?
輸入格式
       輸入第一行為資料組數T (T<=10)。每組資料第一行為一個整數n(1<=n<=1000),即村裡的人
數。以下n 行每行為一個人的名字(僅有小寫字母組成)。輸入保證一個村裡所有人名字的長
度之和不超過1,000,000。
輸出格式
      對於每組資料,輸出所有人名字的字母總數。
樣例輸入                 樣例輸出

1                                              5
3
aaaaa
bbb
abababab

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 1<<30
#define M 1002
#define kind 26
//ascII個數
struct node{
  int  isword;
  node * next[kind];
  node()
  {
      isword=0;
      mem(next,0);
  }
}*root;
int total;//輸出的答案
char s[10002];//
//構建字典樹
void Insert(node *p,char s[])
{
    int index,i=0;
    while(s[i])
    {
        index=s[i]-'a';
        if(p->next[index]==NULL)
          p->next[index]=new node;
        p=p->next[index];
        p->isword++;
        i++;
    }
}
void mycount(node *p)
{
    for(int i=0;i<kind;i++)
     if(p->next[i]!=NULL)
      {
          if(p->next[i]->isword>1)
            total+=p->next[i]->isword;
         mycount(p->next[i]);
      }
}
//釋放這棵字典樹
void myfree(node *p)
{
    for(int i=0;i<kind;i++)
     if(p->next[i]!=NULL)
        myfree(p->next[i]);
     delete p;
}
int main()
{
    int n,T;
    cin>>T;
    while(T--)
    {
        scanf("%d",&n);
        root=new node;
        total=n;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s);
            Insert(root,s);
        }
        mycount(root);
        printf("%d\n",total);
        myfree(root);
    }
    return 0;
}