Asce's Summer Ranking No.1

15 篇文章 0 订阅
12 篇文章 0 订阅
时间限制 1000 ms   内存限制 65536 KB

题目描述

学姐在加入集训队之后,学习了使用ubuntu系统来做题,但是没有了360电脑管家,学姐再也没办法看到她的飞速电脑开机到底虐了全国多少人。作为一个电脑高手,学姐花了几分钟黑到了360的数据库拿到了全国360用户的开机时间,现在学姐想自己算算到底打败了百分之多少的人?

输入格式

输入有多组数据。首先给出数据组数 T(T10) ,下面 T 组数据,每组开头为 n(1n100000) ,360的用户数,和 t ,学姐的开机时间,接下来 n 个数字, ti 代表第 i 个用户的开机时间。其中 t ti 为非负整数且小于 109

输出格式

每组数据一行,输出学姐打败了全国百分之多少的用户,精确到

 

 

 

签到题

整数比较大小

代码略

--------------------------------------------------------------------------------------------------------------------------------------------

时间限制 1000 ms   内存限制 65536 KB

题目描述

趁着放假,学姐去学车好带学弟去兜风。但是学车真的很辛苦,每天五点半就要起床赶班车,但是学姐的教练更辛苦,他们要相同的时间到而且日日如此。于是温柔的学姐关切的问了他们的休息情况,教练告诉她,他们两个人倒班教学姐,每个教练每上 n 天班就会放一天假,如果一个教练放假,就由另一个教练来代课,一直代课到自己放假再换人。 现在学姐想知道,每一天是哪个教练给她上课。

输入格式

输入开始为数据组数 T(T10) ,接下来 T 组输入,第一行为 nm ,我们假设第一天教学姐的是教练1,而且他教学姐的前一天刚刚放完假,教练2则会在学姐上课的第 m 天放假, 1mn  以保证每天都有教练教学姐。接下一行为 q(q103) ,即询问次数,接着 q 行,每行 ti 表示学姐想问哪天的教练是谁。因为教练们非常非常厉害,而且学姐不知道自己到底会花多久学完车,你的程序要处理的 nmti 上限为 109

输出格式

对于每个询问 ti ,输出一行,1或2代表当天的教练。

输入样例

1
5 3
3
6
9
13

输出样例

2
1
2

 

 

水题 坑题 题意难懂 开始读不懂题交了个wa

思想就是找规律划分循环节

详见代码

#include <iostream>
#include <cstdio>
 
using namespace std;
 
int t,n,m,temp,q;
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        scanf("%d",&q);
        while(q--)
        {
            scanf("%d",&temp);
 
            if(temp<=n) {printf("1\n");continue;}
 
            temp=(temp-n)%(n+1);
            if(temp<=m && temp>=1) printf("2\n");
            else printf("1\n");
        }
    }
    return 0;
}


-------------------------------------------------------------------------------------------------------------------------------------------

时间限制 1000 ms   内存限制 65536 KB

题目描述

学姐正在写作业,但是她写着写着就开始想学弟,走神的她就开始在纸上画圈圈。这时学弟突然出现了,好奇的学弟问学姐在做什么,惊慌之下,学姐随口说想算一下这些圆覆盖的面积为多少。学弟顿时非常仰慕学姐,但是学姐突然意识到自己不会做,为了自己能给学弟留下好印象,她来求助你帮她算出来这些圆覆盖的面积。
为了简化问题,我们假设所有圆的半径都为1。

输入格式

输入有多组数据。开头为一个整数 T(T10) ,表示数据组数,接下来T组输入,每组开头为一个整数 n(1n100) ,表示学姐画的圆的个数,接下来 n 行,每行两个整数 xi,yi ,表示圆的圆心坐标, 1xi,yi100

输出格式

输出一个数,表示面积并,精确到小数点后五位。

输入样例

1
2
1 1
2 1

输出样例

5.05482

 

计算几何题

 

真的好麻烦好费时间T.T

个人代码比较挫,按从左到右从上到下的顺序加入圆

每加入一个,就加上圆的面积 同时减去和之前加过的重叠的面积

派的定义我用的4*atan(1),比较精确

注意最好把能用到的重叠的部分圆面积先define一下

define时式子要加括号哈

神犇学长们累加每个1乘1的小方格做的目测比较简单不用算这么多圆的碎片面积0.0

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define PI (4*atan(1))
#define zuida ((2*PI/3)-sqrt(3)/2)
#define cida (PI/2-1)
#define bianyuan (5*PI/12-sqrt(3)/2)
#define sancha  ( 2*(5*PI/12-sqrt(3)/2)-(PI/3-sqrt(3)+1) )
using namespace std;
 
bool table[105][105];
int t,n;
double ans;
int main()
{
 
    scanf("%d",&t);
    while(t--)
    {
        memset(table,false,sizeof(table));
        ans=0;
        scanf("%d",&n);
        while(n--)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            table[x][y]=true;
        }
 
        for(int i=1;i<=100;i++)
            for(int j=1;j<=100;j++)
                if(table[i][j])
        {
            if(table[i-1][j-1])
            {
                if(table[i-1][j])
                {
                    if(table[i-1][j+1])//111
                    {
                        if(table[i][j-1])               //zuida          //jiaoxiao     //bianyuan
                         ans+=PI-(   zuida + 2*(cida) - 2*(bianyuan)   +zuida -sancha);
                         else
                         ans+=PI-(   zuida + 2*(cida) - 2*(bianyuan)   );
                    }
                    else//110
                    {
                        if(table[i][j-1])
                            ans+=PI-(   zuida + cida - (bianyuan) +zuida -sancha  );
                            else
                         ans+=PI-(   zuida + cida - (bianyuan)   );
                    }
                }
                else
                {
                    if(table[i-1][j+1])//101
                    {
                        if(table[i][j-1])
                         ans+=PI-(   2*(cida)  +zuida -bianyuan );
                         else ans+=PI-(   2*(cida)   );
                    }
                    else//100
                    {
                        if(table[i][j-1])
                         ans+=PI-(   cida  +  zuida - bianyuan);
                         else ans+=PI-(   cida  );
                    }
                }
            }
            else
            {
                if(table[i-1][j])
                {
                    if(table[i-1][j+1])//011
                    {
                        if(table[i][j-1])
                            ans+=PI-(   zuida + cida - (bianyuan) + zuida - (bianyuan)  );
                        else
                           ans+=PI-(   zuida + cida - (bianyuan)   );
                    }
                    else//010
                    {
                        if(table[i][j-1])
                           ans+=PI-(   zuida  + zuida - (bianyuan) );
                           else ans+=PI-(   zuida   );
                    }
                }
                else
                {
                    if(table[i-1][j+1])//001
                    {
                        if(table[i][j-1])
                          ans+=PI-(   (cida) + zuida );
                        else
                          ans+=PI-(   (cida)   );
                    }
                    else//000
                    {
                        if(table[i][j-1])
                          ans+=PI - (zuida);
                          else ans+=PI;
                    }
                }
            }
        }
        printf("%.5lf\n",ans);
    }
    return 0;
}


----------------------------------------------------------------------------------------------------------------------------------

时间限制 1000 ms   内存限制 65536 KB

题目描述

给定一个 NM 的矩阵,求问里面有多少个由'#'组成的矩形,"There are 5 ships.",若是里面有一个不是矩形的联通块,则输出"So Sad"

输入格式

1n,m1000

有多组数据,EOF结束。

输出格式

每行对应一个answer

输入样例

6 8
.....#.#
##.....#
##.....#
.......#
#......#
#..#...#
6 8
.....#.#
##.....#
###...##
.......#
##.....#
#..#...#

输出样例

There are 5 ships.
So Sad

 

 
观察观察!!!就是观察!观察观察 终于找到了些简单的规律
当存在不是矩形的联通块时一定存在这样的2乘2方格
.#           ##            ##          #.
##         #.              .#           ##
枚举2乘2方格看有没有这样的 有就sad。。
接下来,剩下的#一定构成矩形啦 只需枚举左上角数个数啦
左上角的条件是#号的左边和上边都是.号
左上边的不一定是.哦
ps有些人观察的姿势弄出了bfs。。也能过
代码~
#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 1005
 
using namespace std;
 
char a[maxn][maxn];
int n,m,ans;
bool flag;
bool pd()
{
    for(int i=2;i<=n;i++)
        for(int j=2;j<=m;j++)
    {
        int tempsum=0;
        if(a[i][j]=='.') tempsum++;
        if(a[i][j-1]=='.') tempsum++;
        if(a[i-1][j]=='.') tempsum++;
        if(a[i-1][j-1]=='.') tempsum++;
        if(tempsum==1) return false;
    }
    return true;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=n;i++) scanf("%s",a[i]);
 
        for(int i=1;i<=n;i++)
            for(int j=m;j>=1;j--)
                a[i][j]=a[i][j-1];
        for(int i=0;i<=max(m,n);i++) {a[0][i]='.';a[i][0]='.';}
        if(!pd()) printf("So Sad\n");
 
        else
        {
            ans=0;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                if(a[i][j]=='#' && a[i][j-1]=='.' && a[i-1][j]=='.') ans++;
 
             printf("There are %d ships.\n",ans);
 
        }
 
 
    }
 
 
 
 
    return 0;
}

------------------------------------------------------------------------------------------------------------------------------------------
时间限制 5000 ms   内存限制 65536 KB

题目描述

用关系“<”和“=”将3个数A、B和C依序排列时有13种不同的序关系:
ABCABCABCABCACBACBBAC

BACBCABCACABCABCBA

现在输入数字的个数,要求你给出上述关系的数目。

数的个数不大于100
 

输入格式

多组数据,EOF结束

每行一个输入

输出格式

对于每个输入,输出一行,即对应答案

输入样例

3

输出样例

13

 

 

组合数学实在蒟蒻。。

比赛后请教了萌萌的黄学姐【ym】,终于会了

如果n个数,用m个小于号和n-m-1个等于号链接起来

等价于把n个不同的小球放入m+1个不同的盒子里,不许有空盒

(这个问题怎么解决,萌萌的黄学姐于是说,用dp)

设dp[i][j]表示把n个球放入m个盒中

考虑放最后一个球的过程,放之前如果有m-1个盒子,就是要加一个放1个球的盒子

插空呗,m-1个盒子算两侧,有m个空

如果放之前有m个盒子,就是把这个球放入任意一个中,有m种

所以dp[i][j]=dp[i-1][j-1]*j+dp[i-1][j]*j;

最后枚举等于号的个数,累加相应dp值就行嘞

这题得高精度,用java的biginteger写~

import java.io.*;
import java.math.*;
import java.util.*;
import java.text.*;
 
public class Main {
    public static void main(String[] args)
    {
        Scanner cin = new Scanner (new BufferedInputStream(System.in));
        int n,i,j;
        BigInteger ans,temp1,temp2;
        BigInteger dp[][]=new BigInteger[105][105];
        for(i=1;i<=100;i++) dp[i][1]=BigInteger.ONE;
        for(j=2;j<=100;j++) dp[1][j]=BigInteger.ZERO;
         
 
        for(i=2;i<=100;i++)
            for(j=2;j<=100;j++)
                dp[i][j]=(dp[i-1][j-1].add(dp[i-1][j])).multiply(BigInteger.valueOf(j));
         
        while(cin.hasNext())
        {
            n=cin.nextInt();
            ans=BigInteger.ZERO;
             
            for(i=1;i<=n;i++)
                ans= ans.add(dp[n][i]);
             
            System.out.println(ans);
        }
         
    }
 
}


--------------------------------------------------

最后附上一道题,和上题一样也是组合数学用dp解得,用来加深印象~。【思路是黄学姐的,再ym。】

时间限制 2000 ms   内存限制 655360 KB

题目描述

There're many bricks with different heights put down on a straight line. When looking from one side, there're only some of them that could be viewed. More specifically, we cannot get a sight of a lower brick behind a higher one. For example, if we have 5 bricks with heights below: 3 5 2 9 8 then we can only see the bricks with heights of 3, 5 and 9 when we take a sight from the left side. Similarly, when we take a view from the right side, we can only see the bricks with height 8 and 9, where the other three bricks are blocked from our line of sight. Now you're given   N  bricks. The only limit comes out that we can only see   L  bricks when taking the view from left side, and   R  bricks from the right. Calculate how many ways we can put down the bricks to achieve it.

输入格式

An integer   T(T10)  will exist in the first line of input, indicating the number of test cases. Each test case consists of one line with three integers   N,L  and   R(1N5000,1L,RN) .

输出格式

Since the answer could be large, you're only required to output the answer modulo   109+7 .

输入样例

1
5 3 2

输出样例

18

 

 

最高的一根棍一定能被看见,我们以这根棍为界把所有的棍分成左右两部分

先从剩下的的n-1根棍中选出i根棍放到左面,其余放到右边,有C[n-1][i]种

左面的i根棍中,有l-1根可以被看见

设i根棍排在一起,有j根棍能被看见为dp[i][j]

每次都放入最小的棍的话,

dp[i][j]=dp[i-1][j-1]         +       dp[i-1][j]*(i-1);

         //最小棍放入后能被看见,在最前面  //最小棍插到其余棍中间或所有棍的最后面,不能被看见

右面的n-i-1根棍同理,可以用一个dp方程

C和dp数组要预处理出来

 

求结果的过程见代码,求之前要if判断一下这种情况能否出现

还有,这题如果数组全开longlong,会mle

我们可以全开int,在转换时先用longlong存中间结果,再换回来

上ac代码

#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 5005
#define mo 1000000007

using namespace std;

int t,n,l,r;
int C[maxn][maxn];

int dp[maxn][maxn];

void MakeC()
{
    C[0][0]=1;
    for(int i=1;i<=5000;i++)
    {
        C[i][0]=1;
        C[i][i]=1;
    }
    for(int i=2;i<=5000;i++)
        for(int j=1;j<i;j++)
        {
            long long temp=((long long)C[i-1][j-1]+(long long)C[i-1][j])%mo;
            C[i][j]=(int)temp;
        }
}
void Makedp()
{
    dp[0][0]=1;
    for(int i=1;i<=5000;i++)
    {
        dp[i][i]=1;
        dp[i][0]=0;
    }
    for(int i=2;i<=5000;i++)
        for(int j=1;j<i;j++)
        {
            long long temp=((long long)dp[i-1][j-1]+(long long)dp[i-1][j]*(i-1))%mo;
            dp[i][j]=(int)temp;
        }
}
int main()
{
    memset(C,0,sizeof(C));
    memset(dp,0,sizeof(dp));
    MakeC();
    Makedp();


    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&l,&r);
        if(l+r>n+1) {printf("0\n");continue;}

        int ans=0;
        for(int i=0;i<=n-1;i++)
        if(i>=l-1 && n-i-1>=r-1)
        {
            long long temp;
            if(dp[i][l-1]<0) printf("aaaaa");
            temp=((long long)C[n-1][i]*(long long)dp[i][l-1]%mo)*(long long)dp[n-i-1][r-1]%mo;
            if(temp<0) printf("wwww");
            ans+=(int)temp;
            ans%=mo;
        }

        printf("%d\n",ans);
    }
    return 0;
}

============EOF===========

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值