1. 程式人生 > >SDUT 2018 Winter Individual Contest

SDUT 2018 Winter Individual Contest

題目連結

* G 記憶化搜尋

題目的意思: 給你兩個陣列a,b 讓a,b兩個陣列按其原序進行組合,問能否組合成為c陣列。

我們可以試著用搜索的方式進行處理,但是由於資料較大,而且在處理的過程中,有重疊的狀態,所以我們需要用到記憶話,對於原先有的狀態之後的搜尋,我們不去在重複,這樣就節省了很多的時間。

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int a[2002],b[2002],c[5003];
long long memory[2002][2002];
int n,m;
int ok = 0
; int dfs(int aa,int bb,int cnt) { if(ok)return 1; if(cnt==n+m) {ok = 1;return 1;} if(memory[aa][bb]!=-1)return memory[aa][bb]; memory[aa][bb] = 0; if(c[cnt]==a[aa]&&aa<=n)memory[aa][bb]|=dfs(aa+1,bb,cnt+1); if(c[cnt]==b[bb]&&bb<=m)memory[aa][bb] |=dfs(aa,bb+1
,cnt+1); return memory[aa][bb]; } int main() { while(cin>>n>>m) { ok = 0; if(n==0&&m==0) { break; } memset(memory,-1,sizeof(memory)); for(int i=1; i<=n; i++)scanf("%d",&a[i]); for(int i=1; i<=m; i++)scanf
("%d",&b[i]); for(int i=1; i<=(n+m); i++)scanf("%d",&c[i]); if(dfs(1,1,1)!=0) printf("possible\n"); else printf("not possible\n"); } return 0; }

H - Post Office
SB題意,題意中有一個病句,就是對最後一種包裹的規格判斷時有一個小於2100的要求,這個是針對它的長度+2*寬+2*厚來說的

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
map<string,int>o;
int main()
{
    double  a,b,c;
    while(cin>>a>>b>>c)
    {
        if(a==0&&b==0&&c==0)break;
        double t[10]={0};
        t[1] = a;
        t[2] = b;
        t[3] = c;
        sort(t+1,t+4);
        a = t[1];
        b = t[2];
        c = t[3];
        int f = 0;
        if(c>=125&&c<=290) {
            if(b>=90&&b<=155)
            {
                if(a>=0.25&&a<=7)
                {
                    f = 1;
                }
            }
        }
        if(c>=125&&b>=90&&a>=0.25)
        {
            if(c<=380&&b<=300&&a<=50)
            {
                if(c>290|b>155|a>7)
                {
                    f  = 2;
                }
            }
        }
          if(c>=125&&b>=90&&a>=0.25)
          {
              if(c+2*(b+a)<=2100)
              {

                      if(c>380|b>300|a>50)
                      {
                          f = 3;
                      }

              }
          }
          if(f==3)printf("parcel\n");
          else if(f==1)printf("letter\n");
          else if(f==2)printf("packet\n");
          else if(f==0)printf("not mailable\n");
    }
    return 0;
}

E Page Count
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 256 Accepted Submission(s): 64
Problem Description
When you execute a word processor’s print command, you are normally prompted to specify the pages you want printed. You might, for example, enter:

10-15,25-28,8-4,13-20,9,8-8
The expression you enter is a list of print ranges, separated by commas.

Each print range is either a single positive integer, or two positive integers separated by a hyphen. In the latter case we call the first integer low and the second one high. A print range for which low > high is simply ignored. A print range that specifies page numbers exceeding the number of pages is processed so that only the pages available in the document are printed. Pages are numbered starting from 1.

Some of the print ranges may overlap. Pages which are common to two or more print ranges will be printed only once. (In the example given, pages 13, 14 and 15 are common to two print ranges.)

Input
The input will contain data for a number of problem instances. For each problem instance there will be two lines of input. The first line will contain a single positive integer: the number of pages in the document. The second line will contain a list of print ranges, as defined by the rules stated above. End of input will be indicated by 0 for the number of pages. The number of pages in any book is at most 1000. The list of print ranges will be not be longer than 1000 characters.

Output
For each problem instance, the output will be a single number, displayed at the beginning of a new line. It will be the number of pages printed by the print command.

Sample Input
30
10-15,25-28,8-4,13-20,9,8-8
19
10-15,25-28,8-4,13-20,9,8-8
0
Sample Output
17
12
題意:給你一個數字是一本書的頁數,然後一行字串代表印刷頁數,但是有些指令是不合法的,可以直接刪除。
分析:多組資料以0結束。使用了一個數組來標記是否被印刷,1為已印刷,0為未被印刷,最後統計1的個數即可。
注意這種問題最後字串末尾的處理,最後一個是沒有逗號的

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
int main()
{

    string name;
    int w[2222];
    int n;
    while(cin>>n)
    {
        if(n==0)break;
        memset(w,0,sizeof(w));
        cin>>name;
        string t;
        int o[3],id;
        int len = name.size();
        id = 1;
        for(int i=0; i<=len; i++)
        {
            if(name[i]==','||i==len)
            {

                o[id] = atoi(t.c_str());
                if(id==2)
                {
                 //   cout<<o[1]<<" "<<o[2]<<endl;
                    for(int j=o[1]; j<=o[2]; j++)
                    {
                        w[j] = 1;
                    }
                }
                else
                {
                    // cout<<o[1]<<endl;

                    w[o[1]] = 1;
                }
                t="";
                id= 1;
            }
            else if(name[i]=='-')
            {
                o[id] = atoi(t.c_str());
                t="";
                id=2;
            }
            else
                t+=name[i];
        }
        int sum =0 ;
        for(int i=1; i<=n; i++)
        {
            if(w[i])sum++;
        }
        cout<<sum<<endl;
    }

    return 0;
}

B 1002 Ropes
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 53 Accepted Submission(s): 41

Problem Description
When climbing a section or “pitch”, the lead climber ascends first, taking a rope with them that they anchor to the rock for protection to ascend. Once at the top of a pitch, the lead climber has the second climber attach to the rope, so they can ascend with the safety of the rope. Once the second climber reaches the top of the pitch, the third attaches, and so on until all the climbers have ascended.
For example, for a 10 meter pitch and 50 meter rope, at most 6 climbers could ascend, with the last climber attaching to the end of the rope. To ascend safely, there must be at least 2 climbers and the rope must be at least as long as the pitch.
This process is repeated on each pitch of the climb, until the top is reached. Then to descend, the climbing rope is hung at its midpoint from an anchor (each half must reach the ground).
The climbers then each rappel from this rope. The rope is retrieved from the anchor by pulling one side of the rope, slipping it though the anchor and allowing it to fall to the ground.
To descend safely, the rope must be at least twice as long as the sum of the lengths of the pitches.
For example, a 60 meter rope is required to rappel from a 30 meter climb, no matter how many climbers are involved.
Climbing ropes come in 50, 60 and 70 meter lengths. It is best to take the shortest rope needed for a given climb because this saves weight. You are to determine the maximum number of climbers that can use each type of rope on a given climb.

Input
The input consists of a number of cases. Each case specifies a climb on a line, as a sequence of pitch lengths as in:
N P1 P2 … PN
Here N is the positive number of pitches, with 1 ≤ N ≤ 100, and Pk is the positive integer length (in meters) of each pitch, with 1 ≤ Pk ≤ 100. The last line (indicating the end of input) is a single 0.

Output
Three numbers for each climb separated by a space, indicating the maximum number of climbers that could use the 50, 60, or 70 meter rope lengths, respectively. State 0 if the given rope length is not suitable for that climb.

Sample Input
1 25
2 10 20
0

Sample Output
3 3 3
0 4 4

有三種登山繩,首先下落時必須要符合要求,即該種登山繩大於所有山峰長度之和的兩倍,其次假定每種登山繩長度為len,則上升時對於每個山峰而言最多承載(len/山峰高度)+1
code:

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
int main()
{
    int n;
    int a[2000];
    while(cin>>n)
    {
        if(n==0)break;
        int ans[10];
        int sum = 0 ;
        memset(ans,inf,sizeof(ans));
        for(int i=1;i<=n;i++)
        {

            scanf("%d",&a[i]);
            sum+=a[i];
            ans[1] = min(ans[1],50/a[i]);
            ans[2] = min(ans[2],60/a[i]);
            ans[3]  = min(ans[3],70/a[i]);
        }
        ans[1]++;
        ans[2]++;
        ans[3]++;
        if(sum*2>50)cout<<"0"<<" ";
        else cout<<ans[1]<<" ";
        if(sum*2>60)cout<<"0"<<" ";
        else cout<<ans[2]<<" ";
        if(sum*2>70)
            cout<<"0"<<endl;
        else cout<<ans[3]<<endl;
    }
}

C: pick定理求格點三角形 Chain Code
參考部落格
Pick 定理: S=a+ b/2 - 1 ,其中 S是圖形面積, a 是圖形內部格點數, b 是邊經過的格點數
適用範圍是:頂點座標均是整點,或者說頂點在格點上的簡單多邊形。
這裡寫圖片描述
就這個題而言,求的是a+b
其中b已知就是題目中輸入的移動的步數
而面積求法,則利用平行四邊形的面積公式求即可,求出來除以二
a+b = (S+n)/2+1; 此處S指整個圍成的面積*2

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
//int dx[]={0 ,1,0,-1,1,-1,1,-1};
int dx[]={1 ,1,0,-1,-1, -1,0,1};
int dy[]={0,1,1,1,0,  -1,-1,-1};
//int dy[]={1,0,-1,0,1,-1,-1,1};
int main()
{
    string temp;
    while(cin>>temp)
    {
        int len = temp.size();
        long long s =0 ;
        long long x=0,y=0,tx,ty;
        for(int i=0;i<len;i++)
        {
            int id = temp[i]-'0';
            tx = x+dx[id];
            ty = y+dy[id];
            s+=(x*ty-y*tx);
            x = tx;
            y = ty;
        }
        if(s<=0)s=-s;
        printf("%lld\n",(len+s)/2+1);
    }
}