CSUST-08.03 组队训练

A - Zero Array Gym - 101853A

题意: 两个操作,第一个操作单点更新。第二个操作是选一个非0数,所有非0数减去这个数,问最少多少次这样的操作可以把所有数字变成0.
思路: 一开始还以为是线段树(队友bb待修改莫队),因为有单点更新,有区间相减。但是仔细理解题目,会发现一个推理的的过程 --> 不考虑0,重复的数字可以缩点,假设从小到大数字为a b c d选一个最小的数字实行一次2操作,会得到0 b - a c - a d - a。再一次忽略0选最小的数字进行2操作会得到 0 c - b d - b 。。。也就是说没进行一次而操作可以减少一种数字。那么我们只要计算除0外的数字种类就可以了。map存一下

ps:维护过程还是有点小问题的,map.size()所有开辟过内存的下标(只要访问过,不管有没有赋值),而修改过程又可能造成额外的访问,所以维护数字个数可以开一个变量而不需要用map.size();

B - New Assignment Gym - 101853B

思路: 网络流??不会

C - Intersections Gym - 101853C

题意: 相同数字连线问连线多少交点
思路: 考虑什么情况会出现交点;假设第一排数字是有序的,下面两个点下标分别为i,j.那么出现交点的条件是i < j 且a[i] > a[j],这正好是逆序对的定义。

在这里插入图片描述

D - Balloons Gym - 101853D

题意: 多少个非0数字

E - Maximum Sum Gym - 101853E

题意: 一个矩阵,每选一个数则相邻的数都不能选,问最大所选的数和。
思路: 状态压缩,首先枚举出每一行的所有合法状态,也就是没有相邻数字。dp[i][j]的状态定义是第i行为j状态时候的值。转移方程为 dp[i][j] = max(dp[i-1][q] + val(i,j) ,dp[i][j]);

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int state[1 << 20],dp[20][1 << 20];
int val[20][20];
int n;

int judge(int x)
{
    if(x & (x << 1))
        return 0;
    return 1;
}

int judge2(int x,int y)
{
    x = state[x];y = state[y];
    if(x & (y << 1))
        return 0;
    if(y & (x << 1))
        return 0;
    if(x & y)
        return 0;
    return 1;
}

int getval(int i,int x)
{
    int ans = 0;
    x = state[x];
    for(int j = 1;j <= n;j++)
    {
        if(x & (1 << (j - 1)))
        {
            ans += val[i][n - j + 1];
        }
    }
    return ans;
}

int main()
{
    
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(dp,0,sizeof(dp));
        scanf("%d",&n);
        for(int i = 1;i <= n;i++)
        {
            for(int j = 1;j <= n;j++)
            {
                scanf("%d",&val[i][j]);
            }
        }
        int cnt = 0;
        for(int i = 0;i < (1 << n);i++)
        {
            if(judge(i))
            {
                state[cnt++] = i;
            }
        }
        int ans = 0;

        for(int i = 0;i < cnt;i++)
        {
            dp[1][state[i]] = getval(1,i);
            ans = max(dp[1][state[i]],ans);
        }
        for(int i = 2;i <= n;i++)
        {
            for(int j = 0;j < cnt;j++)
            {
                int tmp = getval(i,j);
                for(int q = 0;q < cnt;q++)
                {
                    if(judge2(j,q))
                    {
                        dp[i][state[j]] = max(dp[i - 1][state[q]] + tmp,dp[i][state[j]]);
                    }
                }
                ans = max(dp[i][state[j]],ans);
            }
        }
        printf("%d\n",ans);
    }
}

F - Working Time Gym - 101853F
题意: 问时间差大小。

G - Hard Equation Gym - 101853G
题意: y^x=z(mod p) 求x,BSGS。貌似缺数学选手。。。以后再补吧

H - Cube Gym - 101853H I - Circles Gym - 101853I
水过~~

J - Smallest Difference Gym - 101853J
题意: 选出相差小于等于1的最大序列长度。
思路: 注意是 序列 ,而不是串,一上来就写了个单调队列,wa到怀疑人生。。
错误代码

单调队列

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>

using namespace std;
const int maxn = 1e4 + 8;
int val[maxn];
int q_max[maxn],q_min[maxn];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        int ans = 0;
        for(int i = 1;i <= n;i++)
            scanf("%d",&val[i]);
        int h1 = 0,l1 = 0,h2 = 0,l2 = 0;
        q_max[0] = q_min[0] = 0;
        int last = 0;
        for(int i = 1;i <= n;i++)
        {
            while(h1 < l1 && val[q_max[l1]] < val[i])
            {
                l1--;
            }
            q_max[++l1] = i;
            
            while(h2 < l2 && val[q_min[l2]] > val[i])
            {
                l2--;
            }
            q_min[++l2] = i;
            
            while(val[q_max[h1 + 1]] - val[q_min[h2 + 1]] > 1)
            {
                if(q_max[h1 + 1] < q_min[h2 + 1])
                {
                    last = q_max[h1 + 1];
                    h1++;
                }
                else
                {
                    last = q_min[h2 + 1];
                    h2++;
                }
            }
            ans = max(ans,i - last);
        }
        printf("%d\n",ans);
    }
    return 0;
}
//2 8 8 9 0

纯暴力枚举

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;
const int maxn = 1e4;
int a[maxn];

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        for(int i = 1;i <= n;i++)
        {
            scanf("%d",&a[i]);
        }
        int x = 0,y = 0;
        int ans = 0;
        for(int i = 1;i <= n;i++)
        {
            if(a[i] - a[i - 1] == 1 && i > 1)
            {
                y = a[i];
                x = a[i - 1];
                break;
            }
            else if(i > 1 && a[i - 1] - a[i] == 1)
            {
                y = a[i - 1];
                x = a[i];
                break;
            }
            else if(a[i] == a[i - 1] && i > 1)
            {
                x = a[i];
                y = a[i];
            }
        }
//        printf("%d %d\n",x,y);
        int num_x = 0,num_y = 0;
        for(int i = 1;i <= n;i++)
        {
            if(a[i] == x)
            {
                num_x++;
            }
            else if(a[i] == y)
            {
                num_y++;
            }
            if(a[i] - y == 1)
            {
                x = y;
                y = a[i];
                num_x = num_y;
                num_y = 0;
            }
            else if(x - a[i] == 1)
            {
                y = x;
                x = a[i];
                num_y = num_x;
                num_x = 0;
            }
            ans = max(num_x + num_y,ans);
        }
        printf("%d\n",ans);
    }
    return 0;
}

AC代码

#include <cstdio>
#include <map>
#include <algorithm>

using namespace std;
const int maxn = 1e4 + 7;
int a[maxn];
map<int,int>mp;

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        mp.clear();
        int n;
        scanf("%d",&n);
        int maxx = 0;
        for(int i = 1;i <= n;i++)
        {
            scanf("%d",&a[i]);
            maxx = max(maxx,a[i]);
            mp[a[i]]++;
        }
        
        int ans = 0;
        for(int i = 0;i < maxx;i++)
        {
            ans = max(ans,mp[i] + mp[i + 1]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

K - Citations Gym - 101853K
题意: 字符串处理,抽出括号里的字符并输出
思路: 卡getline,得用fgets。而且注意publisher后面没有逗号,而其他的行是有逗号的吗,就是这个点卡了3h,醉了。

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值