第十八届西南科技大学ACM程序设计竞赛(同步赛)签到题 6题

Posted 小哈里

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十八届西南科技大学ACM程序设计竞赛(同步赛)签到题 6题相关的知识,希望对你有一定的参考价值。

文章目录

B 为欢几何

链接:https://ac.nowcoder.com/acm/contest/33540/B
来源:牛客网

题目描述
欢迎各位教练,老师,同学们来到西南科技大学第十八届校赛。在这短暂的五个小时,尽情享受AC , AK的快乐。

藏头诗的本意一般藏在每个诗句的首字,将它们按顺序连起来读会有意想不到的效果。

《水浒传》第六十一回中梁山好汉为了拉卢俊义入伙,“智多星”吴用和宋江便生出一段“吴用智取玉麒麟”的故事来,利用卢俊义正为躲避“血光之灾”的惶恐心理,口占四句卦歌:

芦花丛中一扁舟,

俊杰俄从此地游。

义士若能知此理,

反躬难逃可无忧。

暗藏“卢俊义反”四字,广为传播。结果,成了官府治罪的证据,终于把卢俊义“逼”上了梁山。

现给你一首有 nn 行的"诗" ,你能解读出它的本意吗?
输入描述:
第一行输入一个正整数 nn (1≤n≤8)(1≤n≤8) ,表示"诗"的行数。

保证输入的字符只包含小写字母,每行"诗句"的字符数不超过 1010 。
输出描述:
输出仅一行一个字符串,表示"诗"想表达的本意。
示例1
输入
复制
5
south
west
university
science
technology
输出
复制
swust

  • 题意:给出t个字符串,取每个的第一个字母拼起来输出
  • 思路:for一遍
#include<bits/stdc++.h>
using namespace std;

int main()
    int T;  cin>>T;
    string t = "";
    while(T--)
        string s;  cin>>s;
        t += s[0];
    
    cout<<t<<"\\n";
    return 0;



F 青山隐隐,败叶萧萧

链接:https://ac.nowcoder.com/acm/contest/33540/F
来源:牛客网

题目描述
远山起伏,黑魆魆地时隐时显;枯叶在秋风中飘落翻转。小c 不愿意看到校园里此番凄凉景象,决定动用他的魔法,让校园与身后的青山在秋季一样焕发生机!

我们把问题具象化:小c 面前的 nn 堆败叶堆排成一排,每一堆败叶堆有 a_ia
i

片败叶。如果小c 能够使得面前这一排败叶同时满足以下两个条件,那么小c 就可以发动魔法让这片青山,让这座校园焕发生机!

条件①:对任意 i∈[1,n)i∈[1,n) , a_i+a_i+1a
i

+a
i+1

是一个质数;条件②:对任意 i∈[1,n]i∈[1,n] , a_ia
i

是一个质数。

小c 可以对任意多堆的败叶堆,做任意多次任意操作 (也可以为 00 ):

操作①:令 a_i=a_i+2a
i

=a
i

+2 ;操作 ②:令 a_i=a_i-2a
i

=a
i

−2 。当然,你不可以令任何一堆败叶堆里败叶的数量为负数。

请问小c 能否让青山和校园焕发生机?
输入描述:
第一行输入一个正整数 tt (1≤t≤2×10^3)(1≤t≤2×10
3
) 表示测试数据组数。

每组测试数据第一行输入一个正整数 nn (1≤n≤1314)(1≤n≤1314) 表示败叶堆的堆数。

第二行输入 nn 个非负整数 a_ia
i

(0≤a_i≤1314520)(0≤a
i

≤1314520) ,表示第 ii 堆败叶堆里的败叶片数。
输出描述:
对于每组测试数据,如果可以让青山和校园焕发生机,一行输出一个字符串 “YES” ,否则输出一行一个字符串 “NO” 。(输出不包含引号)
示例1
输入
复制
7
1
0
1
9
2
5 2
2
11 17
3
99 1314520 99999
4
1919 810 114514 314159
6
3 14159 26535 89793 23846 26433
输出
复制
YES
YES
YES
NO
YES
NO
NO
说明
对于第一组测试用例,可以对第 11 堆败叶堆使用 11 次操作①,则序列变为 22 ,满足条件。

对于第二组测试用例,可以对第 11 堆败叶堆使用 11 次操作②,则序列变为 7 7 ,满足条件。

对于第三组测试用例,不需要操作,序列满足条件。

对于第四组测试用例,可以证明,永远无法同时满足两个要求。

对于第五组测试用例,可以对第 11 堆败叶使用 44504450 次操作①,再对第 22 堆败叶堆使用 657259657259 次操作②,最后对第 33 堆败叶使用 608596608596 次操作①,则序列变为 8999,2,13171918999,2,1317191 。

第六、七组样例不再过多阐释。

当然,可能的操作方法不唯一,最后变成的序列也不唯一。

  • 题意:给出长为n的数组,每次可以给一个数+2或-2,求最后能否令每个数以及每次a[i]+a[i+1]都是素数,输出yes或no。
  • 思路:
    因为操作不限制次数,所以不难构造奇数最后都是3,偶数最后都是2,那么每个数都是素数就满足了。
    然后扫一遍判断能否满足a[i]+a[i+1]的条件即可(2+2不行,2+3可以,3+3不行),素数判断可以暴力,即不能有连续的2或3。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5050;
int a[maxn], b[maxn];
#define ios ios::sync_with_stdio(0), cin.tie(0),cout.tie(0)
bool isprime(int n)
	if(n<2)return false;
	for(int i = 2; i <= n/i; i++)
		if(n%i==0)return false;
	
	return true;


int main()
    IOS;
    int T;  cin>>T;
    while(T--)
        int n;  cin>>n;
        int ok = 1;
        for(int i = 1; i <= n; i++)
            cin>>a[i];
            a[i]%=2;
            a[i] += 2;
            b[i-1] = a[i-1]+a[i];
            if(i!=1 && !isprime(b[i-1]))
                ok = 0;
            
        
        if(ok)cout<<"YES\\n";
        else cout<<"NO\\n";
    
    return 0;



G 几番烟雾,只有花难护

链接:https://ac.nowcoder.com/acm/contest/33540/G
来源:牛客网

题目描述
龙山的天气是醉人的温暖,恰好是樱花落尽的时季。散布着细沙的行人道上满是狼藉的粉色花片,有些便沾挂在平铺的碧草上。几树梨花还点缀着嫩白的残瓣。北面与西面小山上全罩着淡蓝色的衣校,小燕子来回在林中穿跳。在这里正是一年好景的残春,到处有媚丽的光景使人流连。

烟烟雾雾,云云霭霭。残春好景使人流连忘返,可是,在这伤春悲秋之时,即使柳树已经抽完了芽,青藤也换完了新枝,而鲜花已经不再盛开。明年的鲜花有,年年新花年年有,可是你曾今看到的那一朵,你永远无法挽留,即使深爱过,再也不会出现。

你引腕便要去挽,获得的只有眼角不受控落下的泪滴。你毅然步入梦中,映入眼帘的是一片开满着蓝色鸢尾花的田野。通过划分可以把这片田野化成无数块 ,第 ii 块的面积为 i^2i
2
个单位面积,第 nn 块的面积为 n^2n
2
个单位面积。每块蓝色鸢尾花田的排布以及面积如图所示:(红色数字 ii 代表蓝色鸢尾花田编号,即第几块)

已知购买第 ii 块蓝色鸢尾花田的一单位面积的价格 price_iprice
i

如下式所示:
price_i = \\begincases \\fracni+1, & n%i ≠ 0 \\ \\fracni ,& n%i=0 \\ \\endcasesprice
i

=
i
n

+1,
i
n

,

n%i


=0
n%i=0

现请你计算将前 nn 片蓝色鸢尾花田全部购买下来所需要的价格。
输入描述:
第一行输入一个正整数 tt (1≤t≤100)(1≤t≤100) ,表示有 tt 组测试数据。

接下来 tt 行,每行输入只有一个正整数 nn (1≤n≤10^9)(1≤n≤10
9
) ,表示要购买的是前 nn 片蓝色鸢尾花田。
输出描述:
共有 tt 行输出。

每行输出只有一个整数,表示将前 nn 片蓝色鸢尾花田全部购买下来所需要的价格。输出可能很大,请你对 998244353998244353 求余。
示例1
输入
复制
5
1
3
1
4
1314520
输出
复制
1
20
1
46
934267671
说明
对于样例 11 :第一块蓝色鸢尾花田的单价是 11 ,面积为 11 ,故购买前 11 片蓝色鸢尾花田的总价格是 1×1=11×1=1 。

对于样例 22 :第一块蓝色鸢尾花田的单价是 33 ,面积为 11 ;第二块蓝色鸢尾花田的单价是 22 ,面积为 44 ;第三块蓝色鸢尾花田的单价是 11 ,面积为 99 。故购买前 33 片蓝色鸢尾花田的总价格是 3×1+2×4+1×9=203×1+2×4+1×9=20 。

你知道蓝色鸢尾花的花语是什么吗? (与本题解题无关)

思路:

  • [n/i]求和,不难想到整除分块(板子),即对于一段[n/i]结果相同的值,比如说10/4=10/5=2,那么[4,5]的n/i是相同的。
  • 那么该段对于答案的贡献就为[n/i]乘以l^2+(l+1)^2+…r^2即可,后者是个平方和公式,初中有推导过,1^2+2^2+…n^2 = n(n+1)(2n+1)/6。
  • 注意因为整除的时候不需要+1,所以可以先把+1算进去,然后n%r==0的时候,再减去r^2即可,注意取模问题,以及除6的时候需要逆元
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0),cout.tie(0)
typedef long long LL;
const LL mod = 998244353;

LL pows(LL a, LL x)  if(x==0)return 1; LL t = pows(a, x>>1); if(x%2==0)return t*t%mod; return t*t%mod*a%mod; 
LL pows(LL a, LL x, LL p)  if(x==0)return 1; LL t = pows(a, x>>1, p); if(x%2==0)return t*t%p; return t*t%p*a%p; 
LL exgcd(LL a, LL b, LL &x, LL &y) if(!b) x = 1, y = 0; return a; elseLL r = exgcd(b, a%b, x, y); LL t = x; x = y; y = t-a/b*y; return r; 
void exgcd(LL a, LL b, LL &d, LL &x,  LL & y, LL MOD)  if (b==0)  d = a; x = 1; y = 0;  else  exgcd(b, a % b, d, y, x, MOD); y -= x * (a / b);  
LL inv(LL a, LL MOD)  LL d=0, x=0, y=0; exgcd(a, MOD,  d,  x, y, MOD); return d == 1 ? (x + MOD) % MOD : -1; 

LL calc(LL l, LL r)//计算l^2+...r^2
    l--;
    LL rel = l*(l+1)%mod*(2*l%mod+1)%mod*inv(6,mod);
    LL rer = r*(r+1)%mod*(2*r%mod+1)%mod*inv(6,mod);
    return (rer-rel+mod)%mod;


int main()
	IOS;
    LL T;  cin>>T;
    while(T--)
        LL n;  cin>>n;
        LL ans = 0;
        for(LL l = 1, r; l <= n; l = r+1) //整除分块,当前区间[l,r]
            r = n/(n/l);
            ans = (ans+(n/l+1)*calc(l,r)%mod)%mod;
            if(n%r==0)ans = (ans-(r)*(r)%mod%+mod)%mod;//整除的时候减掉
        
        cout<<(ans+mod)%mod<<"\\n";
    
    return 0;


H 岸风翻夕浪,舟雪洒寒灯

链接:https://ac.nowcoder.com/acm/contest/33540/H
来源:牛客网

题目描述
如题名称所示,湖岸的风翻起晚浪,舟外的雪飘落灯前。看似写景,实则暗喻实事。杜甫用拟人的手法将浪大和风急的关系揭示出来,并以风来比喻小人猖狂,浪来比喻局势动荡,小人猖狂导致局势动荡。

现有无数重的"浪",我们用 S_xS
x

描述第 xx 重"浪"的波形,"浪"满足以下性质:

S_1=1S
1

=1

S_n = S_n-1+n+S_n-1S
n

=S
n−1

+n+S
n−1

( ‘++’ 表示连接)

例如:S_2=1\\ 2\\ 1S
2

=1 2 1,S_3=1\\ 2\\ 1\\ 3\\ 1\\ 2\\ 1S
3

=1 2 1 3 1 2 1, S_4=1\\ 2\\ 1\\ 3\\ 1\\ 2\\ 1\\ 4\\ 1\\ 2\\ 1\\ 3\\ 1\\ 2\\ 1S
4

=1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 …

第 33 重"浪"的波形图如下所示。

由上述样例波形图和文字解释,可以发现第 33 重"浪"的第 33 位上的"浪高"是 11 ,第 44 重"浪"的第 1010 位上的"浪高"是 22 。

在此基础上推广一下,请你求出第 101010^1010
10
10
10

重"浪"的第 KK 位上的"浪高"是多少?
输入描述:
一行一个正整数 K(1\\le K \\le 10^18)K(1≤K≤10
18
) ,含义如题所示。
输出描述:
仅一行,一个正整数表示答案。
示例1
输入
复制
1
输出
复制
1
示例2
输入
复制
4
输出
复制
3

题意:

  • 给出一个序列,每次下一个序列由当前序列+数字+当前序列组成,不断翻倍,求无限长序列的第k个数字是多少。

思路:

  • 因为指数级增长是很快的,所以可以考虑递推出当前k在第几个序列中,每次长度计算就2*n+1,然后再把k逆着推回去,得到k是在前三个中的第几个,最后输出就行。
  • 如果逆着推的过程中k出现在了某一段的中间,那么就是当前段的序号值。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5050;
typedef long long LL;
#define IOS ios::sync_with_stdio(0), cin.tie(0),cout.tie(0)

int main()
    IOS;
    LL k;  cin>>k;
    if(k==1)cout<<1; return 0;
    LL n = 2, x = 3;
    while(x < k) x=2*x+1, n++;
    while(k > 3 && n>2)
        LL nx = (x-1)/2;
        if(k==nx+1)
            cout<<n<<"\\n";
            return 0;
        else if(k > nx+1)
            k = k-nx-1;
            n--;
            x = nx;
        else
            n--;
            x = nx;
        
    
    if(k==1 || k==3)cout<<"1";
    else cout<<"2";
    return 0;



L 夜暗方显万颗星,灯明始见一缕尘

链接:https://ac.nowcoder.com/acm/contest/33540/L
来源:牛客网

题目描述
人不该太清醒,过去的事情就让它过去,不必反复咀嚼。一生不长,重要的事儿也没那么多。天亮了,又赚了。自认为迷惑的时候,往往才能看清方向与人生美好的可贵与价值意义。

顺应生活之路,无论走向哪种极端,我们都会在不一样的处境找到不一定的答案,从而不断平衡自己。我们需要这样一种能力,也需要去选择认同。自认为不错的时候,往往可以瞥见我们人生生活上本来存在的不足。

浩瀚星辰,万里银河;红烛微尘,夜临灯始。我们把这个夜空看做一个二维平面,则以某一点为原点建立一个笛卡尔坐标系。坐标系内有以下物体:“星”、“尘”、“灯”。

①:"星"是一个 n×mn×m 的矩形区域,它能够发出光芒。其左下角顶点坐标为 (0,0)(0,0) ,右上角顶点坐标为 (n,m)(n,m) 。

②:"尘"是一个 x×yx×y 的矩形区域,它可以也必须完全放置在"星"的表面之上,遮蔽"星"所发出的光芒。保证"尘"至少有一种完全放置在"星"的范围内的方法。

③:"灯"是"尘"遮蔽了"星"之后,"星"剩下的部分 (剩余部分通常是 “LL” 型或 “一字” 型) 。

"灯"中的每一个矩形都能为"灯"提供 11 点能量。给定"星"的位置和"尘"的大小,请制订一个放置"尘"的方案,使得"灯"能提供的总能量最多,求出这个最多的总能量数。("尘"必须完全放置在"星"的范围内,即:“尘” ∪∪ “星” == “星” 且 “尘” ∩∩ “星” == “尘” )
输入描述:
输入仅一行,输入 44 个正整数 n,m,x,yn,m,x,y (1≤n,m≤10^3,1≤x,y≤min(n,m))(1≤n,m≤10
3
,1≤x,y≤min(n,m)) ,分别表示"星"的区域以及"尘"的大小。
输出描述:
输出仅一个整数,表示"灯"最多可以提供的总能量数。
示例1
输入
复制
1 3 1 1
输出
复制
3
示例2
输入
复制
2 3 1 2
输出
复制
9
说明
对于样例 11 ,"星"的区域如图所示:

"尘"的大小为 1×11×1 ,有以下两种方案:

①可以选择让"尘"放置在在最靠左的一个区域内,则"灯"的区域大小是 1×21×2 ,如图所示:

显然,"灯"的区域内一共有 1×11×1 的矩形两块, 1×21×2 的矩形一块,总矩形数是 33 ,故"灯"提供的总能量数是 33 。

②选择让"尘"放置在最中间的区域内,则"灯"的区域是两块的 1×11×1 的矩形区域,如图所示:

显然最后提供的总能量数是 22 ,不如方案①。故本样例中,"灯"最多可以提供的总能量数是 33 。

题意:

  • 给出n*m的矩阵,在里面放一个小号的x*y矩阵(保证能放进去),求没被盖住的部分,子矩阵的个最多有多少。

思路:

  • 不难贪心出肯定是放在角落最优,那么剩余的部分就是一个L形。 考虑一个大的ab矩阵中包含的子矩阵个数=a*(a+1)*b*(b+1)/4,那么可以用两个大矩阵的子矩阵个数减去中间小矩阵重复的矩阵个数即可计算出答案。
  • 关于x,y摆放的方向,可以直接两种放置方法都计算一下取个max即可。注意特判放不进去的情况。
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0),cout.tie(0)
typedef long long LL;

LL calc(LL x, LL y)
    return x*(x+1)*y*(y+1)/4;


int main()
	IOS;
    LL n, m, x, y;  cin>>n>>m>>x>>y;
    LL res = 0;
    if(m-y>=0 && n-x>=0)
        res = max(res, calc(n,m-y)+calc(m,n-x)-calc(m-y,n-x));
    
    if(m-x>=0 && n-y>=0)
        res = max(res, calc(n,m-x)+calc(m,n-y)-calc(m-x,n-y));
    
    cout<<res<<"\\n";
    return 0;

M 劝君终日酩酊醉,酒不到刘伶坟上土

链接:https://ac.nowcoder.com/acm/contest/33540/M
来源:牛客网

题目描述
明净的琉璃杯中,斟满琥珀色的美酒,淅淅沥沥槽床滴,浓红恰似火齐珠,煮龙肝,爆凤髓,油脂白,点点又似泪珠涌,锦乡帷帘挂厅堂,春意呵浓浓,笛声悠扬如龙吟,敲起皮鼓响咚咚,吴娃楚女,轻歌软舞,其乐也融融,何况春光渐老日将暮,桃花如雨,飘落满地红,劝世人,不如终日醉呵呵,一日归黄土,纵是酒仙如刘怜,望一杯,也只是,痴人说梦。

小c 很嗜酒,但是小c 的酒已经喝完了,于是他向酒神祈求一些酒,酒神同意了这个请求。但是酒神有个前提:酒分配的多少由一个游戏来决定,小c 必须精准计算出他每次游戏可以获得多少酒,才能真正获得所有的酒。

游戏规则如下:

每次游戏在一个 n×mn×m 的酒桌上进行,酒桌上每一个格子里都有一坛酒,显然,一共有 n×mn×m 坛酒。

小c 可以行动 kk 次,每次行动有两种选择:

①:拿走某一行上剩余的所有酒。

②:拿走某一列上剩余的所有酒。

为了防止小c 作弊,酒神规定:行动①和行动②必须交替执行,不可以连续执行。

为了让小c 酩酊大醉,现在请你帮助小c 计算,游戏行动结束后,他最多可以获得多少坛酒。
输入描述:
第一行输入一个正整数 tt (1≤t≤10^4)(1≤t≤10
4
) ,表示有 tt 组测试数据。

接下来 tt 行,每行三个正整数 n,m,kn,m,k (1≤n,m≤109,0≤k≤2×109)(1≤n,m≤10
9
,0≤k≤2×10
9
) ,分别表示酒桌的大小和小c 最多允许行动的次数。
输出描述:
输出共有 tt 行,每行输出一个正整数表示答案。
示例1
输入
复制
5
1 1 0
3 3 2
4 9 1
6 7 3
5201314 1314520 998244353
输出
复制
0
5
9
18
6837231279280
说明
对于样例第一组测试数据,由于小c 没有行动次数,所以最终他一坛酒也无法获得。输出 00 。

对于样例第二组测试数据,小c 可以先拿第 22 行 (如图红线,可以拿走 33 坛酒),再拿第 22 列 (如图蓝线,由于交点处的酒已经被拿走了,所以只能拿走剩下的 22 坛),他最终获得酒的总坛数 =3+2=5=3+2=5 坛,输出 55 。如图所示:

对于样例第四组测试数据,小c 可以先拿第 55 行 (如图红线,可以拿走 77 坛酒),再拿第 44 列 (如图蓝线,由于下交点处的酒已经被拿走了,所以只能拿走剩下的 55 坛),再拿第 22 行 (如图红线,由于上交点处的酒已经被拿走了,所以只能拿走剩下的 66 坛),他最终获得的酒的总坛数 = 7+5+6=18=7+5+6=18 坛,输出 1818 。如图所示:

显然,每次拿法可能不一样,但是可以证明,以上样例解释中一定是可以获得最多坛数的拿法。

刘伶:晋人,“竹林七贤”之一,以嗜酒著称,著有《酒德颂》。(与本题无关)

题意:

  • 给出n*m个格子,每次可以拿一行或一列,拿过就没了, 只能行列轮流拿,求拿k次最多可以拿多少。

思路:

  • 因为轮流拿,所以直接n/2*len(行+列)即可,如果有多余的一次机会,就拿行或者列里比较长的更加划算。再考虑拿走以后最后重复拿的就是交集的矩阵部分,所以答案就是(n/2+1)*x+(n/2)*y-xy。
  • 注意特判全部拿走的情况,不进是m+n<=q,还有n<=x或者m<=y也能拿光所有的格子
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0),cout.tie(0)
typedef long long LL;

int main()
	IOS;
    int T;  cin>>T;
    while(T--)
        LL n, m, q;  cin>>n>>m>>q;
        if(n>m)swap(n,m);
		LL x = q/2, y = q/2;
		if(q%2==1)y++;
		if(n+m<=q || n<=x || m <= y || n<=y || m<=x)cout<<n*m<<"\\n";
        else cout<<n*x+m*y-x抛砖引板砖:第十八届赛题畅想

第十八届全国大学生智能车大赛 大疆天途智能仓储创意组

第十四届华中科技大学程序设计竞赛决赛同步赛

第十四届华中科技大学程序设计竞赛决赛同步赛 Beautiful Land

第十八届智能车竞赛赛题建议-车模开挂

第十八届智能车竞赛赛题建议-车模开挂