SDUT 2018 Winter Individual Contest - 3

题目链接

* 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);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值