UESTC往年趣味赛刷题记录

P1508

shallowdream 是一个聪明的帅气的男孩,有一天,一个美丽的漂亮的妹子问了他一个困难的问题:

妹子有价值分别为1,2,3的三张卡片,数量分别是a1,a2,a3,shallowdream可以从中选择一些卡片,他得到的分数是所选卡片的价值之和。

美丽的漂亮的妹子很好奇,shallowdream有多少不同的正整数的分数可以拿到呢?

聪明的帅气的男孩shallowdream怎么会被这样的问题难住呢,他轻而易举就答出了这个问题,然后两个人……

那么单身的你能不能回答出这个问题呢?

Standard Input

三个整数:a1,a2,a3

(0≤a1,a2,a3≤100,000,000)(0 \leq a1,a2,a3 \leq 100,000,000)(0≤a1,a2,a3≤100,000,000)

Standard Output

shallowdream可以得到多少个不同种不同的正整数分数。

Samples

InputOutput
2 1 1
7
0 0 0
0
1 2 3
14

Note

样例一:shallowdream 可以选择(1),(2),(3),(1,3),(2,3),(1,2,3),(1,1,2,3) 就可以得到七种不同的分数:1,2,3,4,5,6,7.

Problem ID1516
Time Limit1000 ms
Memory Limit64 MiB
Output Limit64 MiB
Source第八届ACM趣味程序设计竞赛第三场(正式赛)

题解:

考虑一下a,b,c都不为0的情况下,先把c个3放上去,只要有一个1,一个2,3*c内的所有数都能表达出来。

比如:5=3+2,4=3+1;

接下来在此基础上,把所有的2放上去,同理由于有至少一个1,所以3*c+2*b范围内的数都能表达。

再加上所有的1即可。即ans=3c+2b+a;

假设任意两个为0,肯定答案就是不为0的那个数。

假设只有一个为0,c=0的时候由上面讨论过的情况得知没有影响,可以列入第一种情况。

b=0的时候,判断有没有两个1,如果有就相当于有一个1和一个2满足3*c内所有再加上所有的1即可。

如果只有1个1,那么结果显然只有2c+1

a=0的时候,我们尝试放3会发现规律很难找,先把所有的2放出来。

一般情况下,2 _  2 _ 2 (*) 2 A B _ _ ;3放上去会出现:3、2+3、4+3,能填充满除了1的位置。

再往之后A=6+3=2*3+3;B=10=7+3;

可以看出A用到的是一个3,而B是两个。即所有2之后的每3个中的第一个是2的位置上加一个3,在这个3上再加3得到之后的。

第二个是在之前利用一个3变成5、7的基础上再加一个3,往后第二个位置在2个3的基础上继续加。

第三个显然就是加上3即可。

所以答案就是ans=2*b-1+c+c+c-1=3c+2b-2;

当然如果只有一个2:特殊考虑,相当于1个1和c个3的情况。(因为上面的一般情况肯定是在2&2*2有*号位(由几个2加一个3变成)才出现的,2个2也属于特殊情况:因为它的*号位只有单个3组成,但结论不变所以列入上面的情况)

#include<bits/stdc++.h>
using namespace std;

#define rep(a,b) for(int i=a;i<=b;i++)
#define red(a,b) for(int i=a;i>=b;i--)
#define ULL unsigned long long 
#define LL long long 

int main()
{
    long long a,b,c;
    cin>>a>>b>>c;
    int ans=0;
    if(a==0&&b==0)ans=c;
    else if(a==0&&c==0)ans=b;
    else if(b==0&&c==0)ans=a;
    else if(b==0)
    {
        if(a==1)ans=2*c+a;
        else ans=3*c+a;
    }
    else if(a==0)
    {
        if(b>1)
        {
            ans=2*b-1;
            ans+=c+(c-1)+c;
        }
        else
        {
            ans=2*c+1;
        }
    }
    else ans=a+2*b+3*c;
    cout<<ans<<endl;
    system("pause");
}

P1521

There are N people passing the ball. It starts from the first person, and each time the person who gets the ball should pass the ball to another one. So what is the number of situations in which the ball is passed back to the first person after passing M times.

Standard Input

Including two integers N and M, and N∈[2,9],M∈[1,15].

Standard Output

The answer,and it does not exceed 2^31.

Samples

InputOutput
3 2
2
Problem ID1521
Time Limit1000 ms
Memory Limit64 MiB
Output Limit64 MiB
Source第八届ACM趣味程序设计竞赛第四场(正式赛)

 题解:题意主要是传递M次,从第一个人开始,每次不能传给自己,问最后传给第一个人有多少种情况。

数据较小,暴力递归。

#include<bits/stdc++.h>
using namespace std;

#define rep(a,b) for(int i=a;i<=b;i++)
#define red(a,b) for(int i=a;i>=b;i--)
#define ULL unsigned long long 
#define LL long long 

LL ans=0;int n;int m;
LL dp[100][100];

int main()
{
    cin>>n>>m;
    for(int i=2;i<=n;i++)
        dp[0][i]=0;
        dp[0][1]=1;
    for(int i=1;i<=m;i++)
        for(int j=1;j<=n;j++)
        {
            for(int k=1;k<=n;k++)
             if(k!=j)
             dp[i][j]+=dp[i-1][k];
        }

    if(m<=1||n==1)ans=0;
    cout<<dp[m][1]<<endl;
    system("pause");
}

 P1508

Megumin,是红魔族首屈一指的天才魔法师!她每天会找到n个二维平面上的目标进行爆裂魔法的练习。爆裂魔法覆盖的区域是一个圆形。为了节约魔力,她想要使爆裂魔法覆盖的区域完全包含所有目标的同时(目标可在圆形的边界上),面积最小化。请你帮一下她吧!

来自Megumin的善意提醒:

  1. 请尽量使用double类型存储实数,读入时可以使用%lf。

  2. 输出保留k位小数的实数,可以使用%.kf。

  3. 由于精度误差的原因,在比较两个实数的大小时,你可能要定义一个常数EPSEPSEPS(推荐设为10^(-8)),并参考以下内容:

a < b \iff a-b < -EPS

$a\leq b \iff a-b

Standard Input

输入的第一行包含1个整数n(1<=n<=3),代表Megumin要摧毁的目标数。

接下来n行,每行包含两个实数x,y(-100000<=x,y<=100000),代表一个目标的坐标。

保证n个目标两两不会重合。

Standard Output

输出包含一行三个实数,分别是覆盖所有目标的最小圆的半径,圆心的横坐标,圆心的纵坐标。均保留4位小数。

如果输入只有一个点,最小圆的半径可能会退化为零。

Samples

InputOutput
3
0.0 1.0
0.0 -1.0
1.0 0.0
1.0000 0.0000 0.0000
Problem ID1508
Time Limit1000 ms
Memory Limit64 MiB
Output Limit64 MiB
Source第八届ACM趣味程序设计竞赛第二场(正式赛)

题解:(写了一份题解过了但是用Markdown没保存,懒得写那么详细了)一个点的时候,自己就是圆心。

两个点的时候,取中心作为圆心。

三个点的时候:考虑会不会有相同点导致退化成前两种情况。

再考虑会不会三点一线导致垂直平分线没有交点(这个可以当做后面的钝角三角形来做)

分为钝角三角形和锐角三角形。

前者取最长边的中点作为圆心反而圆最小,后者则要做一个外接圆。

判断钝角三角形:直接算出3条边,利用余弦定理判断有没有负值,如果一旦有,就取出那个最长边进行操作。

如果没有,进入锐角三角形。利用参数式方程(x2,y2)+t1*(x2-x1,y2-y1)的垂直平分线((x1+x2)/2,(y1+y2)/2)+t1*(y1-y2,x2-x1)。

求解t1即可,(我的代码中上面的t1写成了t2)。最后得到t代入直线中求圆心。

代码:我在这里

P1266

四元数是由实数加上三个元素i,j,k组成,而且它们有如下的关系:

i2=j2=k2=−1i^2=j^2=k^2=-1i2=j2=k2=−1

i×j=−j×i=ki \times j=-j\times i=ki×j=−j×i=k

j×k=−k×j=ij\times k=-k\times j=ij×k=−k×j=i

k×i=−i×k=jk\times i=-i\times k=jk×i=−i×k=j

显然,四元数不满足交换律。现在给你一个长度为NNN的四元数乘法表达式(只包含i,j,ki,j,ki,j,k),为了使它的结果等于111,你可以选取表达式中的任意两个数进行交换,但交换次数不能大于MMM次。

若可能使结果为111,输出交换的最少步数。

否则,输出−1-1−1。

Standard Input

第一行包含两个数N(1<=N<=1000), M(0<=M<=1000), 和一个长度为NNN的字符串表示表达式,保证表达式只包含i,j,k。

Standard Output

对于每组数据,若有解,输出最少交换次数;否则输出-1。

Samples

InputOutput
3 2 ijk
1
3 1000 iij
-1

Note

第一组样例:若不进行交换,i×j×k=((i×j)×k)=(k×k)=−1i\times j\times k=((i \times j)\times k)=(k\times k)=-1i×j×k=((i×j)×k)=(k×k)=−1,显然不合法。

最优的一种策略是,只交换i与k,表达式变为k×j×i=((k×j)×i)=(−i×i)=1k\times j\times i=((k\times j)\times i)=(-i\times i)=1k×j×i=((k×j)×i)=(−i×i)=1。

第二组样例:不管怎么交换,结果都不可能为111。

Problem ID1266
Time Limit1000 ms
Memory Limit64 MiB
Output Limit64 MiB
Source第七届ACM趣味程序设计竞赛第三场(正式赛)

 题解:

结论题:显然易见位置的变换只会影响你的正负。

1.答案不是1或者-1,直接输出-1

2.答案是1,输出0

3.答案是-1,判断M是否等于0,等于0输出-1,不等于0说明可以移动。

而从-1移动到1,只需要改变任意两个相邻不同字母的位置。

但是如果字母全部相同也无法改变。最后存在不同字母且M>0初始结果为-1的输出1.

代码:

#include<bits/stdc++.h>
using namespace std;

#define rep(a,b) for(int i=a;i<=b;i++)
#define red(a,b) for(int i=a;i>=b;i--)
#define ULL unsigned long long 
#define LL long long 

int F[100050];
int S[100050];
int flag[100];
int cnt=0;

char cal(char s,char t)
{
    if(s=='i'&&t=='j')return 'k';
    else if(s=='j'&&t=='i'){cnt++;return 'k';}
    else if(s=='j'&&t=='k')return 'i';
    else if(s=='k'&&t=='j'){cnt++;return 'i';}
    else if(s=='k'&&t=='i')return 'j';
    else if(s=='i'&&t=='k'){cnt++;return 'j';}
    else if(s==t){cnt++;return '1';}
    if(s=='1')return t;
}

int main()
{
    int n,m;
    string s;
    char pre,now;
    int ans;
    cin>>n>>m;
    cin>>s;
    if(s.size()==1)ans=-1;
    else
    {
        pre=s[0];int flag=1;
        for(int i=1;i<s.size();i++)
        {
            if(s[i]!=s[0])flag=0;
            now=s[i];
            pre=cal(pre,now);
        }

        if(pre=='1')
        {
            if(cnt%2==0)
            cout<<"0"<<endl;
            else
            {
                if(m==0)cout<<"-1"<<endl;
                else if(flag==1)
                {
                    cout<<"-1"<<endl;
                }
                else cout<<"1"<<endl;
            }    
        }
        else cout<<"-1"<<endl;
    }
    system("pause");
}

P1268 

There are nnn light(s) in a row.These lights are numbered 111 to nnn from left to right.One of the lights are switched on.I wants to switch all the lights on. At each step I can switch a light on(this light should be switched off at that moment)if there’s at least one “very close” light which is already switched on. More exactly: when No.iii light(this light is switched on now),No.jjj light can be switched on(this light is switched off now) if and only if |i-j|<=2. I knows the initial state of lights and I wonder how many different ways there exist to switch all the lights on.

Please find the required number of ways modulo 1000000007(109+7)1000000007 (10^9+7)1000000007(109+7).

Standard Input

The first line of the input contains two integers nnn and mmm where nnn is the number of lights in the sequence and No.mmm light are initially switched on,(1<=n<=1000,1<=m<=n).

Standard Output

In the only line of the output print the number of different possible ways to switch on all the lights modulo 1000000007(109+7)1000000007 (10^9+7)1000000007(109+7).

Samples

InputOutput
3 1
2
Problem ID1268
Time Limit1000 ms
Memory Limit64 MiB
Output Limit64 MiB
Source第七届ACM趣味程序设计竞赛第四场(正式赛)

 题解:越往前做感觉越难了。思路首先是:

假设一开始点亮的是第一盏灯,往后递推的公式是:(F[i]表示在n的范围呢点亮i盏灯)

F[n]=(F[n-1]+(n-1)*F[n-2]),n的范围内只点亮n-2栈灯,就是在n-1中找一盏灯不点,也就是n-1个情况。PS:第n盏灯是要点的,不列入后面的情况。如果点亮的是第m盏灯,就是从m开始往两边递推。

先点左会不会对右边有影响,唯一有影响的是第m-1,影响的是m+1,但这个影响可以由m给予,所以相当于没有影响。

一共要点亮n-1次,这n-1次中挑出点右边的位置:C(n-1,n-m)。假设a[i]表示点亮第i盏灯的方法种数。

F[n]=a[1]*a[2]*a[3]*....*a[n]。而答案等于a[1]...a[m-1]和a[1]...a[n-m]相乘的所有选择左右的排列相加,最后得出前面是组合数C(n-1,n-m),后面是则是相乘,F[m-1]*F[n-m].

#include<bits/stdc++.h>
using namespace std;

#define rep(a,b) for(int i=a;i<=b;i++)
#define red(a,b) for(int i=a;i>=b;i--)
#define ULL unsigned long long 
#define LL long long 

const LL MOD=1e9+7;

LL F[10000],C[2050][2050];


void init()
{
    F[0]=1;F[1]=1;
    for(int i=2;i<=1000;i++)
      F[i]=(F[i-1]+(LL)(i-1)*F[i-2]%MOD)%MOD;
    for(int i=1;i<=2000;i++)
      C[i][0]=1,C[i][i]=1;
    for(int i=1;i<=2000;i++)
        for(int j=1;j<i;j++)
            C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
}

int main()
{
    init();
    int n,m;
    cin>>n>>m;
    
    int ans=1;
    if(m==1)
    {
        if(n==1)cout<<"0"<<endl;
        else cout<<F[n-1]<<endl;
    }
    else
    {
        LL ans=(C[n-1][n-m]*F[n-m]%MOD*F[m-1])%MOD;
        cout<<ans<<endl; 
    }
    system("pause");
}

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
互联网络程序设计是指在互联网上进行程序开发和设计的过程。UESTC则是我国的一所著名高校——电子科技大学。 互联网络程序设计 uestc包含了两个主要的方面:互联网络和程序设计。互联网络是指将多个计算机网络通过通信链路互相连接起来,实现信息共享和资源共享的网络系统。程序设计是指根据需求和目标,通过编写代码和设计算法,实现计算机程序的过程。 互联网络程序设计 uestc的学习内容主要包括以下几个方面: 1. 网络知识:学习互联网络的基本概念、原理和协议,如TCP/IP协议、HTTP协议等。掌握网络编程的基本技术,能够编写网络应用程序。 2. 数据通信:学习数据通信的基本原理和技术,包括数据传输的方式、数据压缩和加密等。了解网络安全和数据保护的基本知识。 3. 程序设计:学习编程语言和开发工具,如Java、C++和Python等。掌握常用的编程技巧和方法,能够设计和实现复杂的网络应用程序。 4. Web开发:学习Web开发的基本知识和技术,包括HTML、CSS、JavaScript等。能够设计和实现交互式的Web应用程序。 5. 数据库技术:学习数据库的基本原理和技术,如SQL语言和数据库管理系统。能够设计和管理数据库,实现数据的存储和检索。 通过学习互联网络程序设计 uestc,可以掌握互联网应用开发的基本技能,具备设计和实现网络应用程序的能力。这对于目前互联网行业的人才需求来说是非常重要的,也为学生提供了广阔的就业和创业机会。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值