《牛客IOI周赛18-普及组》

A:签到题

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<char *,int> pii;
const int N = 105;
const int M = 5e4+5;
const LL Mod = 199999;
#define rg register
#define pi acos(-1)
#define INF 1e9
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
    void print(int x){
        if(x < 0){x = -x;putchar('-');}
        if(x > 9) print(x/10);
        putchar(x%10+'0');
    }
}
using namespace FASTIO;
void FRE(){
/*freopen("data1.in","r",stdin);
freopen("data1.out","w",stdout);*/}

int a[105];
int main()
{
    int n;n = read();
    for(rg int i = 1;i <= n;++i) a[i] = read();
    sort(a+1,a+n+1);
    int len = unique(a+1,a+n+1)-a-1;
    printf("%d %d %d %d\n",a[len]-a[len-1],a[len]-a[2],a[len-1]-a[2],a[len-1]-a[1]);
  //  system("pause");
}
View Code

B: 暴力就行

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<char *,int> pii;
const int N = 105;
const int M = 5e4+5;
const LL Mod = 199999;
#define rg register
#define pi acos(-1)
#define INF 1e9
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
    void print(int x){
        if(x < 0){x = -x;putchar('-');}
        if(x > 9) print(x/10);
        putchar(x%10+'0');
    }
}
using namespace FASTIO;
void FRE(){
/*freopen("data1.in","r",stdin);
freopen("data1.out","w",stdout);*/}

int a[1005],vis[1005];
int main()
{
    int n;n = read();
    LL ans = 0;
    for(rg int i = 1;i <= n;++i) a[i] = read();
    for(rg int i = 1;i <= n;++i)
    {
        memset(vis,0,sizeof(vis));
        int ma = 0;
        for(rg int j = i;j <= n;++j)
        {
            if(vis[a[j]] == 0) ma++;
            vis[a[j]]++;
            ans += ma;
        }
    }
    printf("%lld\n",ans);
   // system("pause");
}
View Code

C:首先,我们可以将路径上所有能到的能量都处理下来。

注意要去重,然后对这个能量做一个排序。

然后去枚举那个数作为上界,可以发现,i位置作为上限,下限选择i-x肯定差距最小(已经排过序)

然后统计最小值即可

这里用了一维数组去模拟二维,因为一开始没有看好数据范围.

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<char *,int> pii;
const int N = 1e6+5;
const int M = 5e4+5;
const LL Mod = 199999;
#define rg register
#define pi acos(-1)
#define INF 1e18
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
    void print(int x){
        if(x < 0){x = -x;putchar('-');}
        if(x > 9) print(x/10);
        putchar(x%10+'0');
    }
}
using namespace FASTIO;
void FRE(){
/*freopen("data1.in","r",stdin);
freopen("data1.out","w",stdout);*/}

int n,m,sx,sy,vis[N],b[4][2] = {1,0,-1,0,0,1,0,-1},top = 0;
unordered_map<LL,int> mt;
LL ans[N],mp[N],d,x;
struct Node{int x,y,step;};
void bfs()
{
    memset(vis,0,sizeof(vis));
    queue<Node> Q;
    if(mp[(sx-1)*m+sy] == -1) return ;
    Q.push(Node{sx,sy,0});
    vis[(sx-1)*m+sy] = 1;
    if(mp[(sx-1)*m+sy] > 0) ans[++top] = mp[(sx-1)*m+sy],mt[mp[(sx-1)*m+sy]]++;
    while(!Q.empty())
    {
        Node q = Q.front();
        Q.pop();
        for(int i = 0;i < 4;++i)
        {
            int px = q.x+b[i][0];
            int py = q.y+b[i][1];
            if(px >= 1 && px <= n && py >= 1 && py <= m && q.step+1 <= d && !vis[(px-1)*m+py] && mp[(px-1)*m+py] != -1)
            {
                vis[(px-1)*m+py] = 1;
                Q.push(Node{px,py,q.step+1});
                LL tmp = mp[(px-1)*m+py];
                if(tmp != 0 && mt[tmp] == 0) ans[++top] = tmp,mt[tmp]++;
            }
        }
    }
}
int main()
{
    int t;t = read();
    while(t--)
    {
        top = 0;
        mt.clear();
        n = read(),m = read(),sx = read(),sy = read(),d = read(),x = read();
        for(rg int i = 1;i <= n;++i)
            for(rg int j = 1;j <= m;++j) mp[(i-1)*m+j] = read();
        bfs();
        if(top < x) printf("no\n");
        else
        {
            sort(ans+1,ans+top+1);
            LL ma = INF;
            for(rg int i = x;i <= top;++i) ma = min(ma,ans[i]-ans[i-x+1]);
            printf("%lld\n",ma);
        }
    }
   // system("pause");
}
View Code

D:

首先,对于一个数,如果它是最小的不能被消耗的法术。

那么,说明比他小的法术都已经被消耗了。那么对于这部分的法术,可以后缀和统计。

所以我们要从大到小排序。

那么,我们可以去枚举已经消耗了多少法术即可。

实际上,统计的是已经消耗j的法术时,最小的不能消耗的法术为a[i]时的方案数。

那么,这部分的方案数显然就是消耗掉j的方案数,那么显然这部分和前面的方案有关。

那么可以发现就是背包计数。

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<string,int> pii;
const int N = 1e5+5;
const int M = 2e5+5;
const LL Mod = 199999;
#define rg register
#define pi acos(-1)
#define INF 1e9
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
    void print(int x){
        if(x < 0){x = -x;putchar('-');}
        if(x > 9) print(x/10);
        putchar(x%10+'0');
    }
}
using namespace FASTIO;
void FRE(){/*freopen("data1.in","r",stdin);
freopen("data1.out","w",stdout);*/}

int a[3005];
LL dp[3005],sum[3005];
int main()
{
    int n,m;n = read(),m =  read();
    for(rg int i = 1;i <= n;++i) a[i] = read();
    sort(a+1,a+n+1,greater<>());
    sum[n] = a[n];
    for(rg int i = n-1;i >= 1;--i) sum[i] = sum[i+1]+a[i];
    LL ans = 0;
    dp[0] = 1;
    for(rg int i = 1;i <= n;++i)//枚举最小的无法使用的法术
    {
        for(rg int j = m;j >= 0;--j)//枚举剩余值j
        {
            if(m < a[i]) break;//过滤过大值
            if(a[i] > m-sum[i+1]-j && j+sum[i+1] <= m) ans += dp[j];//第一个判断,当前值不够用a[i].第二个判断值不超过m
        }
        for(rg int j = m;j >= a[i];--j) dp[j] += dp[j-a[i]];
    }
    printf("%lld\n",ans);
  //  system("pause");
}
View Code

 

posted @ 2020-09-06 08:54  levill  阅读(241)  评论(0编辑  收藏  举报