组队赛第七场

记录一下个人认为有意义的题

大鱼吃小鱼  51Nod - 1289 

有N条鱼每条鱼的位置及大小均不同,他们沿着X轴游动,有的向左,有的向右。游动的速度是一样的,两条鱼相遇大鱼会吃掉小鱼。从左到右给出每条鱼的大小和游动的方向(0表示向左,1表示向右)。问足够长的时间之后,能剩下多少条鱼?Input第1行:1个数N,表示鱼的数量(1 <= N <= 100000)。 
第2 - N + 1行:每行两个数A ii, B ii,中间用空格分隔,分别表示鱼的大小及游动的方向(1 <= A ii<= 10^9,B ii = 0 或 1,0表示向左,1表示向右)。Output输出1个数,表示最终剩下的鱼的数量。Sample Input
5
4 0
3 1
2 0
1 0
5 0
Sample Output
2

我知道这是个水题,但是比赛前一小时没想到用栈,就想了好久,队友说set过了个题,我发现用栈直接能过,以后提醒自己要想全面!

#include<stdio.h>
#include<string.h>
#include<queue>
#include<set>
#include<stack>
using namespace std;
int main()
{
    stack<int>q;
    int n,a,b,sum;
    scanf("%d",&n);
    sum=n;
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&a,&b);
        if(b==1)
            q.push(a);
        else
        {
            while(!q.empty())
            {
                int s=q.top();
                if(a>s)
                {
                    sum--;
                    q.pop();
                }
                else
                {
                    sum--;
                    break;
                }
            }
        }
    }
    printf("%d\n",sum);
}
聪明的木匠   51Nod - 1117 

一位老木匠需要将一根长的木棒切成N段。每段的长度分别为L1,L2,......,LN(1 <= L1,L2,…,LN <= 1000,且均为整数)个长度单位。我们认为切割时仅在整数点处切且没有木材损失。
木匠发现,每一次切割花费的体力与该木棒的长度成正比,不妨设切割长度为1的木棒花费1单位体力。例如:若N=3,L1 = 3,L2 = 4,L3 = 5,则木棒原长为12,木匠可以有多种切法,如:先将12切成3+9.,花费12体力,再将9切成4+5,花费9体力,一共花费21体力;还可以先将12切成4+8,花费12体力,再将8切成3+5,花费8体力,一共花费20体力。显然,后者比前者更省体力。
那么,木匠至少要花费多少体力才能完成切割任务呢?
Input第1行:1个整数N(2 <= N <= 50000) 
第2 - N + 1行:每行1个整数Li(1 <= Li <= 1000)。Output输出最小的体力消耗。Sample Input
3
3
4
5
Sample Output
19

简单贪心,有人有用set做的,我感觉用优先队列会更好,反向思路,每次找到最小的两个之和。

#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;
priority_queue<int ,vector<int >,greater<int> >q;
int main()
{
    int n,x;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
      scanf("%d",&x);
      q.push(x);
    }
    int ans=0;
    int a,b;
    while(q.size()>1)
    {
        a=q.top();
        q.pop();
        b=q.top();
        q.pop();
        ans+=a+b;
        q.push(a+b);
    }
    printf("%d\n",ans);
    return 0;
}

Friend Number II   zoj3336

Given a positive integer x, let S(x) denotes the sum of all x's digits. Two integers x and y are friend numbers if S(x)=S(y). Here comes the problem: Given a positive integer x, of course it has a lot of friend numbers, find the smallest one which is greater than x,please.

Input

There are multiple test cases. The first line of input is an integer T (0<T<230) indicating the number of test cases. Then T test cases follow. Each case is an integer x (0<x<=101000).

Output

For each test case, output the result integer in a single line.

Sample Input

3
12
19
222

Sample Output

21
28
231

Note: No input data start with digit 0 and you should not output a number starts with 0.

题意:找到y是的每位数的和等于x,并且y要大于x,要最小的那个

思路:本以为是全部加9,但是一组样例9991就失败了,然后我发现先找末尾不是0的数,让它减一,再继续找不是9的数加一,因为9牵扯到金味德问题,所以不考虑他,如果找完了都没找到不是9的数,那么就手动填一个1,有组样例比如5299,那么我们会找到变成5398,那么我们让98sort一下。

#include<stdio.h>
#include<string.h>
#include<string>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
char s[100005];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",s);
        int len=strlen(s),j;
        for(int i=len-1;i>=0;i--)
        {
            if(s[i]!='0')
            {
                s[i]--;
                j=i-1;
                break;
            }
        }
        for(j;j>=0;j--)
        {
            if(s[j]!='9')
            {
                s[j]++;
                break;
            }
        }
        if(j<0)
            printf("1");
        sort(s+j+1,s+len);
        printf("%s\n",s);
    }
}

军舰游戏 51Nod - 1521 

在游戏开始的时候,爱丽丝放k个战舰在这个表格中,并不把具体位置告诉鲍博。每一只战舰的形状是 1×a 的长方形(也就是说,战舰会占据a个连续的方格)。这些战舰不能相互重叠,也不能相接触。

然后鲍博会做一系列的点名。当他点到某个格子的时候,爱丽丝会告诉他那个格子是否被某只战舰占据。如果是,就说hit,否则就说miss。

但是这儿有一个问题!爱丽丝喜欢撒谎。他每次都会告诉鲍博miss。

请你帮助鲍博证明爱丽丝撒谎了,请找出哪一步之后爱丽丝肯定撒谎了。


Input单组测试数据。 
第一行有三个整数n,k和a(1≤n,k,a≤2*10^5),表示表格的大小,战舰的数目,还有战舰的大小。输入的n,k,a保证是能够在1×n的表格中放入k只大小为a的战舰,并且他们之间不重叠也不接触。 
第二行是一个整数m(1≤m≤n),表示鲍博的点名次数。 
第三行有m个不同的整数x1,x2,...,xm,xi是鲍博第i次点名的格子编号。格子从左到右按照1到n编号。Output输出一个整数,表示最早一次能够证明爱丽丝一定撒谎的点名编号。如果不能证明,输出-1。点名的编号依次从1到m编号。Sample Input
样例1
11 3 3
5
4 8 6 1 11

样例2
5 1 3
2
1 5
Sample Output
样例输出1
3

样例输出2
-1

思路:开始的时候先找到所有的最多的放几个,然后每次找一个点去掉,然后看一下还能放几个,每次减去不能再放的个数,如果放战舰的个数少于k就输出第几个m就可以了,另外要注意一个点,战舰不能接触,那么每次都要除以a+1

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define ll long long
int v[2*100005];
int main()
{
    memset(v,0,sizeof(v));
    int n,k,a;
    scanf("%d%d%d",&n,&k,&a);
    int m;
    scanf("%d",&m);
    int maxx=(n+1)/(a+1),x,l,r,ans,flag=-1;
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&x);
        v[x]=1;
        for(l=x-1;l>=1&&v[l]==0;l--);
        for(r=x+1;r<=n&&v[r]==0;r++);
        ans=(r-l)/(a+1)-(x-l)/(a+1)-(r-x)/(a+1);
        maxx-=ans;
        if(maxx<k&&flag==-1)
        {
            flag=i;
            break;
        }
    }
    printf("%d\n",flag);
}

补题:FZU - 2148

Fat brother and Maze are playing a kind of special (hentai) game in the clearly blue sky which we can just consider as a kind of two-dimensional plane. Then Fat brother starts to draw N starts in the sky which we can just consider each as a point. After he draws these stars, he starts to sing the famous song “The Moon Represents My Heart” to Maze.

You ask me how deeply I love you,

How much I love you?

My heart is true,

My love is true,

The moon represents my heart.

But as Fat brother is a little bit stay-adorable(呆萌), he just consider that the moon is a special kind of convex quadrilateral and starts to count the number of different convex quadrilateral in the sky. As this number is quiet large, he asks for your help.

Input

The first line of the date is an integer T, which is the number of the text cases.

Then T cases follow, each case contains an integer N describe the number of the points.

Then N lines follow, Each line contains two integers describe the coordinate of the point, you can assume that no two points lie in a same coordinate and no three points lie in a same line. The coordinate of the point is in the range[-10086,10086].

1 <= T <=100, 1 <= N <= 30

Output

For each case, output the case number first, and then output the number of different convex quadrilateral in the sky. Two convex quadrilaterals are considered different if they lie in the different position in the sky.

Sample Input
2
4
0 0
100 0
0 100
100 100
4
0 0
100 0
0 100
10 10
Sample Output
Case 1: 1
Case 2: 0

唉,比赛时没时间了,后来看了下找到题发现还蛮简单的,考虑凹包

题意:给你n个点,看能组成几个凸包,我们反其道而行之,找凹包,因为是四边形,凹包就是第四个点肯定在其他三个点组成的三角形内,那么其他三个点组成的三角形面积就是,其他三个点与第四个点组成的三角形之和。Sabc=Sabd+Sbcd+Sacd。那么我们只需要判断不是凹包的情况就行了

#include<math.h>
#include<string>
#include<stdio.h>
#include<algorithm>
using namespace std;
const double esp=10e-6;
struct point
{
    int x;
    int y;
};
double area(point a, point b, point c)
{
    return fabs(1.0*((b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x)))/2.0;
}
bool check(point a, point b, point c, point d)
{
    if (fabs(area(a,b,c)-area(a,b,d)-area(b,c,d)-area(a,c,d))<esp)
        return 0;
    return 1;
}
int main()
{
    int t,casee=0;
    scanf("%d",&t);
    while(t--)
    {
        point p[35];
        int n;
        int cnt = 0;
        scanf("%d",&n);
        for (int i = 0; i < n; i++)
            scanf("%d%d",&p[i].x,&p[i].y);
        for (int i=0; i<n; i++)
            for (int j=i+1; j<n; j++)
                for (int k=j+1; k<n; k++)
                    for (int l=k+1; l<n; l++)
                    {
                        if (check(p[i],p[j],p[k],p[l])&&check(p[i],p[l],p[k],p[j])&&check(p[i],p[j],p[l],p[k])&&check(p[l],p[j],p[k],p[i]))
                            cnt++;
                    }
        printf("Case %d: %d\n",++casee,cnt);
    }
}

猜你喜欢

转载自blog.csdn.net/zezzezzez/article/details/80159105