nwu 新生题解【第一套】

A:【读题+细节】
【排序+贪心】
题意:
有n张牌,分给n/2个人,每人两张,要求每个人牌上的数值之和相等,输入保证有解。
题解:
先将所有牌面排序,那么依次给每个人分配【最小,最大】【次小,次大】。。。。。。即可【学习按关键字排序】

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <queue>
#include <list>
#include <cstdio>
#define IO ios_base::sync_with_stdio(0),cin.tie(0)
#define N 105
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n;
struct Node{
    int id,val;
}node[N];

bool cmp(Node x, Node y){
    return x.val < y.val;
}
int main()
{
    while(cin >> n){
        for(int i = 1;i <= n;++ i){
            cin >> node[i].val;
            node[i].id = i;
        }
        sort(node+1, node+n+1, cmp);
        for(int i = 1;i <= n/2;++ i)
            cout << node[i].id << " " << node[n-i+1].id << endl;
    }
    return 0;
}



B:【读题+细节】
题意:
给你t,s,x。且有一个序列是这样的t, t + s, t + s + 1, t + 2s, t + 2s + 1, 问你x是否存在这个序列当中
题解:
直接判断即可,注意1、x < t 2、 t+s*k+1 时必须有一个s

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <queue>
#include <list>
#include <cstdio>
#define IO ios_base::sync_with_stdio(0),cin.tie(0)
#define N 105
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int t,x,s;
int main()
{
    while(cin >> t >> s >> x){
        if(x < t){
            cout << "NO" << endl;
            continue;
        }
        if((x-t)%s == 0 || ((x-t-1)%s == 0 && (x-t-1)/s != 0))
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

C:【求余+技巧】
题意:
给定两个数n,m。求有多少个数 (x+y)%5 == 0。1 <= x <= n, 1 <= y <= m;
题解:
朴素解法:
一个嵌套双重for循环去枚举,这样的话会超时。
优化:
题意要求能整除5的数字,那么考虑一下,其实只有 0+0,1+4,2+3,3+2,4+1 这四种情况。
其他的数字均可以转化成求这四种情况的问题,那么进行求余操作可以很优美的实现这个目的。
ps:这是个开放题,各种解法都是可以的。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <queue>
#include <list>
#include <cstdio>
#define IO ios_base::sync_with_stdio(0),cin.tie(0)
#define N 105
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n,m;
ll a[10],b[10];
int main()
{
    while(cin >> n >> m){
        memset(a, 0, sizeof(a));
        memset(b, 0, sizeof(b));
        for(int i = 1;i <= n;++ i)  a[i%5]++;
        for(int i = 1;i <= m;++ i)  b[i%5]++;

        ll ans = a[0]*b[0] + a[1]*b[4] + a[2]*b[3] + a[3]*b[2] + a[4]*b[1];
        cout << ans << endl;
    }
}



D:【读题】
题意:
balabala一大堆,其实就是让你判断是否有一个人成绩 after > before && before >= 2400
题解:
直接模拟这个过程就好

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <queue>
#include <list>
#include <cstdio>
#define IO ios_base::sync_with_stdio(0),cin.tie(0)
#define N 105
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n,after,before;
string s;
int main()
{
    while(cin >> n){
        int ok = 0;
        for(int i = 1;i <= n;++ i){
            cin >> s >> before >> after;
            if(before >= 2400 && after > before)
                ok = 1;
        }
        cout << (ok == 1 ? "YES" : "NO") << endl;
    }
    return 0;
}


E:【读题+模拟】
题意:
给你n个人要推墙,告诉你每个人的高度和墙的高度,如果人的高度 > 墙,需要消耗2能量,否则消耗1能量。求消耗总能量。
题解:
读懂题之后直接模拟

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <queue>
#include <list>
#include <cstdio>
#define IO ios_base::sync_with_stdio(0),cin.tie(0)
#define N 105
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int x,n,h;
int main()
{
    while(cin >> n >> h){
        int ans = 0;
        for(int i = 1;i <= n;++ i){
            cin >> x;
            if(x > h)   ans += 2;
            else
                ans += 1;
        }
        cout << ans << endl;
    }
    return 0;
}


F:【直接构造 or 思维】
题意:
给定一个字符串是这个样子的 123456789101112131415....... 让你求第n个字符是多少。
题解:
一、
按照题意直接定义一个字符串,让它不断 +字符1,+字符2,+字符3......因为n最大1000,然后直接输出即可。n最大1000,所以不会超空间。
二、
首先通过n我们可以判断这一位是在 1位数,2位数,还是3位数。
其次,我们可以计算出该位数的数字是多少,通过减去低位的总数来计算。
最后,分类讨论一下该位数是这个数字的十位、百位、还是千位。
最后输出即可。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <queue>
#include <list>
#include <cstdio>
#define IO ios_base::sync_with_stdio(0),cin.tie(0)
#define N 105
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n;
int ans[3005];

void fuc(){
    int len = 1;
    for(int i = 1;i <= 1000;++ i){
        if(i < 10)  ans[len++] = i;
        if(i >= 10 && i < 100){
            ans[len++] = i/10;
            ans[len++] = i%10;
        }
        if(i >= 100){
            ans[len++] = i/100;
            ans[len++] = (i/10)%10;
            ans[len++] = i%10;
        }
    }
}
int main()
{
    fuc();
    while(cin >> n){
        cout << ans[n] << endl;
    }
    return 0;
}
/*
第二种解法:
int n;
int main()
{
    while(cin >> n){
        if(n < 10)  cout << n << endl;
        if(n >= 10 && n <= 189){
            int res = n-9;
            int num = (res%2 == 0 ? res/2 : res/2+1) + 9;
            cout << (res%2 == 0 ? num%10 : num/10) << endl;
        }
        if(n > 189 && n <= 1090){
            int res = n-189;
            int num = (res%3 == 0 ? res/3 : res/3+1) + 99;
            if(res%3 == 0)  cout << num%10 << endl;
            else if(res%3 == 1) cout << num/100 << endl;
            else if(res%3 == 2) cout << (num/10)%10 << endl;
        }
    }
    return 0;
}
*/


G:【模拟】
题意:
给你三个数字n,a,b分别表示一个圆圈的点数,起点位置,需要走的步数。b > 0:顺时针,b < 0:逆时针。最后求这个人在哪个点。
题解:
根据起点+方向+步数直接模拟。注意考虑负数取模的情况。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <queue>
#include <list>
#include <cstdio>
#define IO ios_base::sync_with_stdio(0),cin.tie(0)
#define N 105
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n,a,b;
int main()
{
    while(cin >> n >> a >> b){
        if(b < 0)   b = -(-b)%n;
        a += n;
        int ans = ((a+b)%n == 0 ? n : (a+b)%n);
        cout << ans << endl;
    }
    return 0;
}


H:【简单判断+技巧】
题意:
给定n和x,表示有一个n*n的矩阵,每个点的元素值是i*j。求这个矩阵中x出现的次数;
题解:
朴素解法:写个双重for循环直接判断即可,但是题目n最大可能是1e5,两个嵌套循环会超时。
优化:考虑到每一行每个元素都可以用行号确定,因此枚举每一行,判断x/i的商是否在1-n之间即可

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <queue>
#include <list>
#include <cstdio>
#define IO ios_base::sync_with_stdio(0),cin.tie(0)
#define N 105
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n,x;
int main()
{
    while(cin >> n >> x){
        int ans = 0;
        for(int i = 1;i <= n;++ i){
            if(x%i == 0 && x/i >= 1 && x/i <= n)
                ans++;
        }
        cout << ans << endl;
    }
    return 0;
}


I:【读题+排序】
题意:
给定n个人以及每个人的票数a[i],现在想让第一个人票数最高。
每个人可以给第一个人投票,投票后这个人的票数减少。
问这个人最少需要增加多少。
题解:
一、
每次从 2-n 这些人中选择最高的给第一个人投票,直到这些人的最高票数比第一个人低。
二、
可以采用c++STL里面的一个工具【优先队列】,实现每次得到最大或者最小数。有兴趣的同学可以百度.

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <queue>
#include <list>
#include <cstdio>
#define IO ios_base::sync_with_stdio(0),cin.tie(0)
#define N 105
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n,vote,a[N];
int main()
{
    while(cin >> n){
        cin >> vote;
        for(int i = 2;i <= n;++ i)
            cin >> a[i];

        int ans = 0;
        while(true){
            sort(a+2, a+1+n);
            if(vote > a[n]) break;
            ans++;
            vote++;
            a[n]--;
        }
        cout << ans << endl;
    }
    return 0;
}


J:【读题+排序】
题意:
给你n个点在x轴的位置,求每个点与其它的最小距离和最大距离。
题解:
考虑到所有点都只在x轴上,那么可以将所有点进行排序。
考虑第i个点的位置,它与其它点的最小距离是去与它相邻的两个点的最小值。
即 : min(a[i+1]-a[i], a[i]-a[i-1])
最大值: max(a[i]-a[1], a[n]-a[i]);
特殊考虑一下第一个点和最后一个点即可

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <queue>
#include <list>
#include <cstdio>
#define IO ios_base::sync_with_stdio(0),cin.tie(0)
#define N 100000+5
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n,a[N];
int main()
{
    while(cin >> n){
        for(int i = 1;i <= n;++ i)
            cin >> a[i];
        sort(a+1, a+n+1);

        cout << a[2]-a[1] << " " << a[n]-a[1] << endl;
        for(int i = 2;i < n;++ i){
            cout << min(a[i+1]-a[i], a[i]-a[i-1]) << " ";
            cout << max(a[n]-a[i], a[i]-a[1]) << endl;
        }
        cout << a[n]-a[n-1] << " " << a[n]-a[1] << endl;
    }
    return 0;
}



原文地址:https://www.cnblogs.com/Jstyle-continue/p/6351925.html