浙江财经大学校赛热身赛

A:

签到题,输出任意两个相加为n的数,推荐解法是直接输出0和n本身。看到这道题第一反应就是输出n-1和1,但当n=-100000的时候会输出1和-100001,超出数据范围会wa。我第一遍就是这样写的,后来加了个判断就过了。

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    int n;
    int x;
    while(cin>>n)
    {
        for(int i=1;i<=n;i++)
        {
            cin>>x;
            if(x>0)
                printf("Case #%d: %d %d\n",i,1,x-1);
            else
                printf("Case #%d: %d %d\n",i,-1,x+1);
        }
    }
    return 0;
}

B:

因为要求第10^18项,普通做法肯定都不行的,所以要找循环节。一般循环节在四十位以内就能得到,然后计算一下就好了。

具体代码等下会传上来。


C:

这道题题意就是从许多根棍子中取出一些组成三角形,问最多能组成几个三角形。

用状态压缩去做。


D:

这道题先打表看一下有没有规律,然后你会发现每一项的值都是它本身加上3,直接从L+3遍历到R+3。因为要遍历很多次,根据抽屉原理可知如果在这个区间大于P,则必定会出现P的倍数。对P取余后自然为0,所以会简化很多。自己当初做的时候没这样做,我是直接去乘然后取余,如果为零直接跳出(如果这样做要注意不要在乘的过程中爆掉)。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int main()
{
    int n;
    long long int l,r;
    int p;
    while(cin>>n)
    {
        for(int i=1;i<=n;i++)
        {
            cin>>l>>r>>p;
            long long int res=1;
            for(long long int j=l+3;j<=r+3;j++)
            {
                (res=j%p*res)%=p;
                if(!res)
                    break;
            }
            if(!res)
                printf("Case #%d: 0\n",i);
            else
                printf("Case #%d: %lld\n",i,res);
        }
    }
    return 0;
}


E:

这道题题意就是给你一个地图,如果本身是0,上下左右1的数量大于1,那么就是一个隐藏房间。给你一个坐标,然后UDLR分别代表上下左右,问你从给定坐标走一下之后是隐藏房间的概率。

直接遍历整张图记录有多少个隐藏房间,然后判断给定坐标走动之后是否为隐藏房间就行了。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int T;
int n,m;
int x,y;
char c;
int mp[110][110];
bool check(int x,int y)
{
    int cmp=0;
    if(mp[x][y])
        return 0;
    if(x>0&&x<=n&&y>0&&y<=m)
    {
        if(mp[x-1][y])
            cmp++;
        if(mp[x+1][y])
            cmp++;
        if(mp[x][y+1])
            cmp++;
        if(mp[x][y-1])
            cmp++;
    }
    return cmp>1;
}
int main()
{
    while(cin>>T)
    {
        for(int k=1;k<=T;k++)
        {
            cin>>n>>m;
            int res=0;
            memset(mp,0,sizeof(mp));
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    cin>>mp[i][j];
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    if(check(i,j))
                        res++;
                }
            }
            cin>>x>>y;
            cin>>c;
            if(c=='U')
                x--;
            if(c=='D')
                x++;
            if(c=='L')
                y--;
            if(c=='R')
                y++;
            if(check(x,y))
                printf("Case #%d: 1/%d\n",k,res);
            else
                printf("Case #%d: 0\n",k);
        }
    }
    return 0;
}

F:

纪念品分组

group.pas/c/cpp

题目描述

元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得 的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。

你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。


输入格式

输入文件group.in包含n+2:

1行包括一个整数w,为每组纪念品价格之和的上眼2行为一个整数n,表示购来的纪念品的总件数G

3-n+2行每行包含一个正整数Pi (5 <= Pi <= w3)w表示所对应纪念品的价格。


输出

输出文件group.out仅→行,包含一个整数, ep最少的分组数目合


样例输入

100
9     
90     
20     
20     
30     
50     
60     
70     
80     
90 

样例输出

6

数据范围

50%的数据满足: 1 <=n <= 15

100%的数据满足: 1 <= n <= 30000, 80 <= W <= 200

直接暴力。。排序之后取最小和最大看相加之后是否大于限制,大于的话R--,不大于就L++,R--。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
    int n;
    int w;
    int s[100100];
    while(cin>>w)
    {
        cin>>n;
        for(int i=0;i<n;i++)
            cin>>s[i];
        sort(s,s+n);
        int l=0;
        int r=n-1;
        int res=0;
        while(l<=r)
        {
            if(l==r)
            {
                res++;
                break;
            }
            if(s[l]+s[r]>w)
            {
                r--;
                res++;
            }
            else
            {
                l++;
                r--;
                res++;
 
            }
        }
        cout<<res<<endl;
    }
    return 0;
}

G:

最大公约数和最小公倍数问题

时间限制: 1 Sec   内存限制: 125 MB
提交: 66   解决: 28
[ 提交][ 状态][ 讨论版]

题目描述

输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数。

条件:

1. P,A是正整数;

2. 要求P,Q以x0为最大公约数,以y0为最小公倍数。

试求:

满足条件的所有可能的两个正整数的个数。


输入

每个测试文件只包含一组测试数据,每组两个正整数x0和y0(2<=x0<100000,2<=y0<=1000000)


输出

对于每组输入数据,输出满足条件的所有可能的两个正整数的个数。

下面是对样例数据的说明:

输入3 60

此时的P Q分别为:

    3     60
    15   12
    12   15
    60   3

所以,满足条件的所有可能的两个正整数的个数共4种。


样例输入

3 60

样例输出

4

比较优秀的做法是用y0/x0,在得到的数之中找质数对数的个数。我前面是这样写的,但是有些地方可能不太对,所以一直wa。后来用一个暴力的方法过了。。。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int gcd(long long int a,long long int b)
{
    return b==0?a:gcd(b,a%b);
}
int main()
{
    long long int a;
    long long int b;
    while(cin>>a>>b)
    {
        int res=0;
        long long int s=a*b;
        if(a==b)
        {
            cout<<1<<endl;
            continue;
        }
        for(int i=a;i<=sqrt(s*1.0);i++)
        {
            if(s%i==0&&gcd(s/i,i)==a)
                res++;
        }
        res*=2;
        cout<<res<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/b_r_e_a_d/article/details/79598626