2017年浙江工业大学大学生程序设计迎新赛热身赛 部分题解

A 毕业设计选题

题目描述

又到了一年一度,大四老学长们毕业设计选题的时候,一般指导老师都会为学生提供若干个选题供学生选择。大家都知道,有的课题,看上去高大上,实则含金量不高,有的课题看似简单,但实际难度却非常大,也有的课题,没有什么太大难度,但却异常繁琐,工作量极大。现大致评估出每个课题的高大上值,实际工作量。已知小飞学长,是个懒惰的家伙,但却又极好面子,因此,请帮他找出高大上值和实际工作量比值最大的课题。

输入描述:

共有T组数据。(T<=10),每组数据第一行有一个整数n(n<=200000),接下来n行,每行一个课题名称(只包含大小写字母,长度小于40),以及该课题的高大上值v,以及其工作量w。(v,w都是小于109的整数)。

输出描述:

对于每组样例输出一个课题名称,代表该组样例中高大上值和实际工作量比值最大的课题(保证唯一)。
示例1

输入

1
2
CloudComputingBasedOnDistributedSystems 5 2
PotentialRisksInRegularSystem 4 2

输出

CloudComputingBasedOnDistributedSystems
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
 
const int maxn=2e5+7;
struct node
{
    char name[40];
    double v,w;
}a[maxn];
 
int main ()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,pos;
        scanf("%d",&n);
        double ans=0;
        for(int i=0;i<n;i++)
        {
            scanf("%s %lf %lf",a[i].name,&a[i].v,&a[i].w);
            double temp=a[i].v/a[i].w;
            if(temp>ans) {ans=temp,pos=i;}
        }
        printf("%s\n",a[pos].name);
    }
    return 0;
}
C 画三角

题目描述

小学时,JYM和XJ刚刚学习了三角形,XJ提议把眼睛闭起来在纸上画三角形,巩固知识。为了让三角形更好地表示,JYM去拿了一张坐标纸(不要问为什么小学的他就有坐标纸),坐标纸的范围是[-1000,1000]。于是,XJ就在坐标纸上画了N个三角形(当然他也可能画了一条直线出来)。因为小学的他们还没有学习小数,所以所有的三角形顶点的坐标,都被JYM近似成了整数点。现在,JYM和XJ想知道这些三角形有没有将坐标原点包含在里面,请你编写程序解决这个问题。

输入描述:

一个整数N(N<1000),表示有N个三角形。接下来每一行有两个整数x(-1000<=x<=1000)和y(-1000<=y<=1000),表示一个点的坐标;每三行的三个点构成一个三角形。

输出描述:

为每个三角形输出一个YES或者NO。YES表示三角形包含了坐标原点,NO表示三角没有包含坐标原点或者坐标原点在三角形的边界上或者当前的三个点不能构成三角形。
示例1

输入

3
1 1
-1 -1
1 0
0 0
1 0
-1 -1
1 0
0 1
-1 -1

输出

NO
NO
YES
#include <cstdio>
#include <iostream>
using namespace std;
 
struct Point{
    int x;
    int y;
    Point(int a, int b) :x(a), y(b){ }
    friend ostream& operator<<(ostream &os, Point &p);
};
 
int cross(const Point &a, const Point &b, const Point &p)
{
    return (b.x - a.x)*(p.y - a.y) - (b.y - a.y)*(p.x - a.x);
}
 
bool toLeft(const Point &a, const Point &b, const Point &p)
{
    return cross(a, b, p) > 0;
}
 
bool inTriangle(const Point &p, const Point &a, const Point &b, const Point &c)
{
    bool res = toLeft(a, b, p);
    if (res != toLeft(b, c, p))
        return false;
    if (res != toLeft(c, a, p))
        return false;
    if (cross(a, b, c) == 0)    //ABC is in one line
        return false;
    return true;
}
 
ostream& operator<<(ostream &os, Point &p)
{
    os << "(" << p.x << ", " << p.y << ") " ;
    return os;
}
 
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int x1,y1,x2,y2,x3,y3;
        scanf("%d %d %d %d %d %d",&x1,&y1,&x2,&y2,&x3,&y3);
        Point A(x1,y1);
        Point B(x2,y2);
        Point C(x3,y3);
        if(x1*y2==x2*y1||x1*y3==x3*y1||x1*y3==x3*y1){cout <<"NO"<<endl;continue;}
        Point P(0,0);
        if (inTriangle(P, A, B, C))
            cout <<"YES"<<endl;
        else
            cout <<"NO"<<endl;
    }
 
    return 0;
}
J Forever97与寄信

题目描述

Forever97与未央是一对笔友,他们经常互相写信。有一天Forever97去邮局寄信,发现邮局的收费方式变成了按字收费,收取的费用为总字数除了其自身以外的最大因子。虽然Forever97是一个有情调的人,但他不想因新收费方式而破财,所以他打算把信分成几份寄出去来减少邮费。已知Forever97写的信共有n个字,可以拆成无数封信,也可以不拆,每封信最少为2个字。求Forever97最少需要付多少邮费?

输入描述:

第一行一个正整数T(T<=200),表示共有T组数据。

第2至第T+1行每行一个正整数n(2<=n<=108)。

输出描述:

对每组数据输出一行,即Forever97最少需要付的邮费。
示例1

输入

3
5
6
9

输出

1
2
2

说明

对于第二组数据,一封6字信可以拆分成两封3字信,各付1邮资。
对于第三组数据,一封9字信可以拆分成一封2字信和一封7字信,各付1邮资。
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
 
bool is_prime(int n)
{
    for(int i=2;i*i<=n;i++)
        if(n%i==0) return false;
    return true;
}
 
int main ()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        if(n%2==0&&n!=2) printf("2\n");
        else
        {
            if(is_prime(n)) printf("1\n");
            else
            {
                if(!is_prime(n-2)) printf("3\n");
                else printf("2\n");
            }
        }
    }
    return 0;
}

L cayun日常之赏月

题目描述

在cayun星球月亮大小都有一个规律,月亮为每30天一个周期,在这30天的周期里,月亮的大小分别为0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,虽然天气很冷,但某个cayun今天却异常疯癫,不知为何居然想要赏月了。但他想在赏月之前知道今天的月亮到底有多大。

输入描述:

第一行数据组数T(T <= 30),
对于每组数据两个整数a, b(0 <= a, b <= 15),表示前两天的月亮大小,保证数据是合法的。

输出描述:

每组数据占一行,表示今天的月亮大小。
示例1

输入

2
0 1
11 10

输出

2
9
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
 
int a,b;
int main ()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&a,&b);
        if(a<b&&b!=15) printf("%d\n",b+1);
        else if(a==1&&b==0) printf("1\n");
        else if(a==14&&b==15)printf("14\n");
        else if(a>b) printf("%d\n",b-1);
    }
    return 0;
}

M cayun日常之三七配对

题目描述

不知道因为什么玄学上的原因,某个cayun特别喜欢3和7这个数字,现在他面前来两个数组,他想知道从这两个数组中各取一个数,有多少种方式可以使得两者和为3或者7的倍数。

输入描述:

第一行数据组数T(T <= 10)
对于每组数据,第一行两个正整数n, m(0 < n, m <= 100000),接下来两行分别为代表两个数组a, b,其中0 <= a[i], b[i] < 10000。

输出描述:

对于每组数据输出一行,代表答案。
示例1

输入

1
2 1
1 4
20

输出

2
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
 
int a,b;
int main ()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m,key;
        int a3[1000000]={0},a7[1000000]={0},b3[1000000]={0},b7[100000]={0},a21[1000000]={0},b21[100000]={0};
        scanf("%d %d",&n,&m);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&key);
            int k1=key%3;
            int k2=key%7;
            int k3=key%21;
            a3[k1]++;
            a7[k2]++;
            a21[k3]++;
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d",&key);
            int k1=key%3;
            int k2=key%7;
            int k3=key%21;
            b3[k1]++;
            b7[k2]++;
            b21[k3]++;
        }
        long long  ans=0;
 
        for(int i=0;i<=2;i++)
            for(int j=0;j<=2;j++)
            if((i+j)%3==0) ans+=(a3[i]*b3[j]);
 
        for(int i=0;i<=6;i++)
            for(int j=0;j<=6;j++)
                if((i+j)%7==0) ans+=(a7[i]*b7[j]);
 
        for(int i=0;i<=20;i++)
            for(int j=0;j<=20;j++)
                if((i+j)%21==0) ans-=(a21[i]*b21[j]);
                if(ans<0) ans=0;
        printf("%lld\n",ans);
    }
    return 0;
}
E 递推
时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld

题目描述

JYM和XJ转眼就从小学上了高中。在学习递推的时候,JYM在纸上随手写了一个递推关系式:a n=2*a n-1,a 0=0。写完这个递推式,JYM拿给XJ看,XJ觉得太过简单,于是大笔一挥,在等式右边又加了一个式子,变成了这样:a n=2*a n-1+n 2。JYM看到这个式子,想要算几个项来看看,可是一算就发现这个数据量太大了,你能帮他解决这个问题吗?

输入描述:

输入数据有多组(不超过100组数据),每组数据包含一个整数N<=1018

输出描述:

一个整数X,表示递推式第n项的值。由于数字太大,因此结果对于1000000009取模后输出。
示例1

输入

0
1
2
3

输出

0
1
6
21
#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;
typedef long long LL;
LL mod=1000000009;

LL P(LL x,LL n)
{
	if(n==1) return x;
	if(n==0) return 1;
	LL m=P(x,n/2)%mod;
	return ((n%2==1?x:1)*m%mod*m%mod)%mod;
}
void deal(LL x)
{
	LL ans1=(P(2,x)%mod*6)%mod;
	LL ans2=P(x%mod,2)%mod;
	LL ans3=((x%mod)*4)%mod;
	LL ans4=6;
	LL ans=ans1%mod-ans2%mod;
	while(ans<0) ans+=mod;
	ans%=mod;
	ans=ans%mod-ans3%mod;
	while(ans<0) ans+=mod;
	ans%mod;
	ans=ans%mod-ans4%mod;
	while(ans<0) ans+=mod;
	if(ans>=mod) ans%=mod;
	printf("%lld\n",ans);
}

int main()
{
	LL n;
	while(~scanf("%lld",&n))
    {
		deal(n);
	}
	return 0;
}



  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值