2019寒假集训新生考试

序言:

为期一周的欢乐的寒假集训终于结束了,很高兴能认识这么多的大佬和学长、学姐。很感谢ljw学长和陈宇老师为我们寒假培训所作出的贡献。

简单点评一下今天的考试试题,就在比赛前的中午,jlw学长说题目很水,很水,你们能信吗??反正我是信了,其实真的是很水(我太弱了),啊啊啊,还有一些题巨坑......话不多说,先放一下今天比赛的一些情况吧。

Information:

Sattus:

Rank List:

黑能,蒋世超布莱克,果光,谜题熊,老魏,孙芾(fu)岳真的好强呀!!

题目:

problem A:28的因子(NEFU 2101)

核心思路:暴力,先判断最多有几个7(位数越少他就会越小),然后一一枚举,看哪个条件符合,我太菜了,这是我最后AC的题,给想复杂了!

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

int main()
{
    //ios::sync_with_stdio(false);(玄学如果不注释会re)
    int n;
    while (~scanf("%d", &n))
    {
        int sum2 = 0;
        int flag = 0, ans1, ans2; //4,7
        sum2 = n / 7;             //7的最大数量
        for (int i = sum2; i >= 0; i--)
        {
            int tmp = n;
            if ((tmp - i * 7) % 4 == 0)
            {
                flag = 1;
                ans1 = (tmp - i * 7) / 4; //标记4的个数
                ans2 = i;                 //标记7的个数
                break;
            }
        }
        if (!flag)
            cout << "xinganheixiong" << endl;
        else
        {
            for (int i = 1; i <= ans1; i++)
                cout << "4";
            for (int i = 1; i <= ans2; i++)
                cout << "7";
            cout << endl;
        }
    }
    return 0;
}

problem B:陈老师发奖金(NEFU 2077)

核心思路:简单的结构体排序。

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

const int M = 1e5 + 5;
struct student
{
    int xh, cy, eng, math;
    int sum;
    int flag;
} a[M];

bool cmp(student a, student b)
{
    if (a.sum != b.sum)
        return a.sum > b.sum;
    else
    {
        if (a.eng != b.eng)
            return a.eng > b.eng;
        else
        {
            return a.flag > b.flag;
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    int n;
    while (cin >> n)
    {
        memset(a, 0, sizeof(a));
        for (int i = 1; i <= n; i++)
        {
            cin >> a[i].xh >> a[i].cy >> a[i].eng >> a[i].math;
            a[i].flag = i;
            a[i].sum += a[i].math + a[i].cy;
        }
        sort(a + 1, a + 1 + n, cmp);
        int tmp;
        if (n < 4)
            tmp = n;
        else
            tmp = 4;
        for (int i = 1; i <= tmp; i++)
            cout << a[i].xh << " " << a[i].sum << endl;
    }
    return 0;
}

problem C:小明分蛋糕(NEFU 2096)

核心思路:本题类似于分整钱,简单题,要能看穿它正负情况是一样的话,就能很快做出来;

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

int main()
{
    int t;
    int a, b, x;
    int ans;
    cin >> t;
    while (t--)
    {
        cin >> a >> b;
        x = fabs(a - b);
        ans = 0;
        while (x >= 5)
        {
            ans += x / 5;
            x -= x / 5 * 5;
        }
        while (x >= 2)
        {
            ans += x / 2;
            x -= x / 2 * 2;
        }
        while (x >= 1)
        {
            ans += x / 1;
            x -= x / 1;
        }
        cout << ans << endl;
    }
    return 0;
}

problem D:神奇的事情发生了(NEFU 2090)

核心思路:栈的运用,由于栈练习较少,我直接用字符串写的。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    char a[105], b[105];
    while (cin >> a)
    {
        int sum = 0, L;
        L = strlen(a);
        for (int i = 0; i < L; i++)
        {
            b[sum] = a[i];
            if (b[sum] == 'o' && b[sum - 1] == 'o') //变化
            {
                b[sum - 1] = 'O'; //移位
                sum--;            //两个变成一个
            }
            if (b[sum] == 'O' && b[sum - 1] == 'O') //删除
                sum -= 2;                           //一次是删除两个
            sum++;//继续进行
        }

        for (int i = 0; i < sum; i++)
            cout << b[i];
        cout << endl;
    }
    return 0;
}

problem E:jwMM选酒店(NEFU 2083)

核心思路:不能暴力,会超时,核心思路,模拟,状态的转移;关注点在当前酒店是否能喝奶茶,如果能喝,就更新到这个位置的所以同色酒店的数量,ans+=当前同色酒店的数量(除本酒店以外);如果不能喝,就ans+=同色的酒店数量(此时的同色酒店数量是一定满足在当前酒店前能喝到奶茶)。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int M = 2e5 + 5;
LL ans = 0;
int color[M] = {0};
int num[55] = {0}; //同颜色酒店的数量
int main()
{
    ios::sync_with_stdio(false);
    int n, m, pp, pos = 0;       //pos是标记能喝奶茶位置的最大值
    cin >> n >> m >> pp;         //酒店个数,颜色数目,最低消费
    for (int i = 1; i <= n; i++) //暂时要住的
    {
        int col, ppi;
        cin >> col >> ppi;
        color[i] = col; //储存第i个位置是什么颜色
        if (ppi <= pp)  //i酒店能奶茶,加上之前的所以同色的酒店就ok
        {
            for (int j = pos + 1; j <= i; j++) //更新每种颜色酒店的数量
                num[color[j]]++;
            pos = i; //更新位置
            ans += num[col] - 1;
        }
        else //i酒店不能喝奶茶,就加之前同色酒店数量就行
            ans += num[col];
    }
    cout << ans << endl;
    return 0;
}

problem F:jwMM的射箭游戏(NEFU 2078)

核心思路:gcd的运用(gcd就是代表的是公因子),坑点x-y可能有小于等于0的情况,要不是这一点,一血就是我的了QAQ~~坑。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    int x1, y1, x2, y2;
    while (cin >> x1 >> y1)
    {
        int num[500] = {0}, z = 0;
        cin >> x2 >> y2;
        int tmp1, tmp2;
        tmp1 = __gcd(x1, y1);
        tmp2 = x2 - y2;
        if (tmp2 <= 0) //这个判断十分重要,题干说是正倍数
            cout << "N" << endl;
        else
        {
            if (__gcd(tmp1, tmp2) == 1) //如果是1的话他就没有除1以外的公因子
                cout << "N" << endl;
            else
                cout << "Y" << endl;
        }
    }
    return 0;
}

problem G:丹青玩游戏(NEFU 2082)

核心思路:二进制枚举,当时没有看出来,同时也要能清楚知道题干的叙述。

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

struct lam
{
    int kg[15];
} a[15];

int main()
{
    ios::sync_with_stdio(false);
    int n, m, tmp, tmp2;
    while (cin >> n >> m) //n是开关数量,m是灯泡数量
    {
        long long ans = 0;
        int pi[15] = {0};
        memset(a, 0, sizeof(a));
        for (int i = 1; i <= m; i++) //输入灯泡及其开关编号
        {
            cin >> tmp;
            for (int j = 1; j <= tmp; j++)
            {
                cin >> tmp2;
                a[i].kg[tmp2] = 1; //代表的是第ki编号的灯泡是否有相应的开关,即开关标记
            }
        }
        for (int i = 1; i <= m; i++) //输入灯泡亮的程度;
            cin >> pi[i];
        for (int i = 0; i < (1 << n); i++) //枚举n(开关数量)
        {
            int dp[15] = {0};
            for (int j = 0; j < n; j++)
            {
                if (i & (1 << j)) //枚举开关开闭的状态
                    dp[j + 1] = 1;
                else
                    dp[j + 1] = 0;
            }
            int z, judge = 0;
            for (int k = 1; k <= m; k++) //判断每一个是否成立
            {
                int sum = 0;
                for (z = 1; z <= n; z++)
                    if (a[k].kg[z] && dp[z]) //ki编号的灯是否有相应的开关
                        sum++;
                if (sum % 2 != pi[k]) //亮度的判断
                {
                    judge = 1;
                    break;
                }
            }
            if (!judge)
                ans++;
        }
        cout << ans << endl;
    }
    return 0;
}

problem H:分糖果(NEFU 2100)

核心思想:二分查找。你的ans一定会小于m值,目的是找到两个数的取余后的加和最大。

  1. 利用取余的性质(a+b)%m=(a%m+b%m)%m(a+b)%m=(a%m+b%m)%m,对输入进行处理。
  2. 从i=1,一直查到i=n,最理想中的返回值是m-1,所以对其当作切入点,利用lower_bound()查找大于等于m-a【i】的坐标。
  3. 关键:细节处理,设查找的数是tmp,lower_bound()的防越界处理,当a【i】中的所有数都小于tmp的时候,他的返回值是1+n,是会越界的,要进行后越界处理;当a【i】中的所有数都小于tmp的时候,他的返回值是1,但是你要找的是小于最近一个tmp,要是减去1也是会出界,要做前出界处理。
  4. 最后一步,如果没有取到x为m-a[i]-1的话就不一定是最优解 所以和最后一个数相加判断。
#include <bits/stdc++.h>
using namespace std;
const int M = 1e5 + 5;
int a[M], m;

int main()
{
    ios::sync_with_stdio(false);
    int t;
    cin >> t;
    while (t--)
    {
        int n;
        memset(a, 0, sizeof(a));
        cin >> n >> m;
        for (int i = 1; i <= n; i++)
        {
            cin >> a[i];
            a[i] %= m;
        }
        sort(a + 1, a + 1 + n);
        int tmp1, tmp2, ans = 0;
        for (int i = 1; i <= n; i++)
        {
            tmp1 = m - a[i];
            tmp2 = lower_bound(a + 1, a + 1 + n, tmp1) - a;
            if (tmp2 - 1 > 0 && tmp2 != 1 + n) //双倍防越界
            {
                if (tmp2 - 1 != i)
                    ans = max(ans, a[tmp2 - 1] + a[i]);
                else if (tmp2 - 2 > 0) //如果他俩是同一个位置,就要向前移一位,不能加本身的
                    ans = max(ans, a[tmp2 - 2] + a[i]);
            }
            if (i != n) //防止加不到最大值的时候
                ans = max((a[i] + a[n]) % m, ans);
        }
        cout << ans << endl;
    }
    return 0;
}

 

problem I:抹发胶(NEFU 2088)

核心思路:暴力。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    int t;
    while (cin >> t)
    {
        int n, a[105];
        while (t--)
        {
            int minn[105] = {0};
            cin >> n;
            for (int i = 1; i <= n; i++)
            {
                cin >> a[i];
                for (int j = 1; j < i; j++) //在输入的同时判断前一名是否小于后一名
                {
                    if (a[i] > a[j])
                        minn[i]++;
                }
            }
            for (int i = 1; i <= n; i++)
            {
                cout << minn[i];
                if (i == n)
                    cout << endl;
                else
                {
                    cout << " ";
                }
            }
        }
    }
    return 0;
}

problem J:天哥的难题(NEFU 2085)

核心思路:数学证明题,后续证明。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
LL fastpow(LL a, LL b)
{
    int res = 1;
    while (b)
    {
        if (b & 1)
            res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}
int main()
{
    ios::sync_with_stdio(false);
    int m;
    while (cin >> m)
    {
        cout << fastpow(3, m) << endl;
    }
    return 0;
}

problem K:煊哥的数字游戏(NEFU 2084)

核心思路:防AK的题,巨无敌难的数学推导。异或是不进位的加法。

  1. sum=a1+a2+...+am,num=a1⊕a2⊕...⊕am。这样就是解sum+b=num⊕2*b。
  2. 若两边相等,则它的二进制每一位都要相等,模拟等式左边+b,等式右边⊕2*b的过程,从第一位逐个比较,直到sum=num。
  3. 当sum=num的时候,等式左边=sum+b=sum',要解b,只需要sum'-sum即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int a[100005];
int main()
{
    ios::sync_with_stdio(false);
    int m;
    LL sum = 0, num = 0, tmp, i = 0;
    cin >> m;
    for (int i = 1; i <= m; i++)
    {
        cin >> a[i];
        sum += a[i];
        num ^= a[i];
    }
    LL ans = sum; //记录原来的sum
    num *= 2;
    while (sum != num)
    {
        i++;
        tmp = (LL)1 << i; //比较每一位是否相同
        if (sum % tmp != num % tmp)
        {
            sum += tmp >> 1;
            num ^= tmp;
        }
    }
    cout << sum - ans << endl;
    return 0;
}

problem L:吃辣条

核心思路:快排+暴力。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    int n;
    while (cin >> n)
    {
        int a[105];
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        sort(a + 1, a + 1 + n);
        cout << a[n - 1] << " " << a[2] << endl;
    }

    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值