第17届BIT校园编程竞赛 - 现场赛(The 17-th BIT Campus Programming Contest - Onsite Round)

题库链接:Dashboard - The 17-th BIT Campus Programming Contest - Onsite Round - Codeforces

一.小P玩钢4

一.题目展示
 Problem - G - Codeforces

小 P 在合肥玩了一天,晚上回到酒店后决定开一把钢铁雄心4。钢铁雄心4是一款二战模拟器,玩家可以操纵部队进攻敌国。玩了没多久,小 PP 很快便包围了敌军的部队。

具体来说,当前这一片战场可以看成是一块 n×m 的网格,每个格子上有一个数字,第 i行第 j 列的数字为 𝑎𝑖,𝑗。如果 𝑎𝑖,𝑗>0,则代表这块格子上有数量为 𝑎𝑖,𝑗 的敌军部队,如果 𝑎𝑖,𝑗=0,则代表这块格子上是我军部队。在这片战场之外也全是我军部队。

显然,这些敌军部队深陷我军的包围之中,我们需要快速消灭包围圈中的敌人。我们每次可以选择一块与我军部队相邻的有敌军的格子(假设是第 i 行第 j列),然后一共需要消耗 𝑎𝑖,𝑗 加上这个格子四周的敌军部队数量之和个单位的装备消灭掉这个格子上的敌人,随后我军部队进入这个格子,𝑎𝑖,𝑗 变为 00。

由于战场宽度的限制,导致每个格子最多只有一个敌军部队,即 𝑎𝑖,𝑗∈{0,1}。现在小P 想要知道,最少消耗多少装备能够消灭掉所有敌军部队?

Input
第一行输入两个整数 n,m𝑛,𝑚 (1≤n,m≤1000),表示战场的行数和列数。

接下来 n𝑛 行,每行输入 m𝑚 个整数,第 i 行第 j 个数为 𝑎𝑖,𝑗 (𝑎𝑖,𝑗∈{0,1})。

Output
输出一行,即最少消耗的装备数量。

Examples 例子
Inputcopy    Outputcopy
5 5
0 0 0 0 0
0 0 0 1 0
0 1 1 1 0
0 0 1 0 0
0 0 0 0 0
9
Note 注意
在样例中,我们可以先攻击 a3,3 的部队,需要消耗 1+3=4 个单位的装备。接下来攻击 a3,4的部队,需要消耗 1+1=2 个单位的装备。接下来三个剩下的敌军部队任选一个顺序攻击即可。因此总的花费为 9。可以证明不存在更优的方案。

二.解题思路


考虑两对相邻的有敌人的格子,可以发现无论先攻击哪一个都会多消耗1个单位的装备。

所以最后的花费和进攻顺序是没有关系的。

因此答案就是  敌人总数量    加上  有  多少对敌人是相邻   的。

三.代码解析


   ①统计敌人数量

for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            cin>>a[i][j];
            if(a[i][j]==1)sum++;//   累加敌人数量
        }
    }

②统计相邻敌人对数量

void xinglin(int u,int v)
{
    b[u][v]=1;
    for(int k=0;k<4;k++)
    {
        x=u+dx[k];
        y=v+dy[k];
        if(a[x][y]==1&&b[x][y]==0)
        {
            sum++;//   四周存在敌人,即为相邻。 
        }
    }    
}

四.代码展示

#include<iostream>//03G - 小P玩钢蹦(VJ) 

using namespace std;

int a[1010][1010],b[1010][1010];
int sum=0;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
int x,y;
void xinglin(int u,int v)
{
	b[u][v]=1;
	for(int k=0;k<4;k++)
	{
		x=u+dx[k];
		y=v+dy[k];
		if(a[x][y]==1&&b[x][y]==0)
		{
			sum++;
			
		}
	}	
}
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			cin>>a[i][j];
			if(a[i][j]==1)sum++;
		}
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			if(a[i][j]==1&&b[i][j]==0)
			{
				xinglin(i,j);	
			}
		}
	}
	cout<<sum<<endl;
	return 0;
}

二.str进制

一.题目展示

str,一个充满着神秘气息的字符串。

它既可以是某位 jiker 的姓名缩写,也可以表示字符串这个单词的缩写,由于其多变的特性,我们可以定义str进制字符串,下面的符合下面进位规则的进制称为该字符串下的 str 进制:

给出一个str进制字符串,每位上的数字x表示该位上是逢x𝑥进1。

给定某个字符串s,再给出一个十进制下的整数d,求d在str进制下的表示值。

Input

第一行输入两个整数m,n (1≤m≤1000,1≤n≤10),代表 str 进制字符串的长度和d𝑑的位数。

第二行输入一个字符串s𝑠 (2≤si≤9),表示 str 字符串。

第三行输入一个整数,表示d𝑑 (0≤d≤10^10)。

数据保证d𝑑能够在str进制下被表示出来。

Output

输出一行一个 m 位的整数,为整数d在 str 进制下的表示。(包括前导零)

Example

input

4 1

2664

8

output

0020

二.解题思路

用整数对字符串的每一位求余并记录下来(注意整数范围10^10,可以选用long long 类型数据存储),之后记录进位数在对字符串的下一位求余  重复此过程。

三.代码展示

#include<iostream>//03K-str进制 
#include<string>

using namespace std;

int main()
{
	int m,n,d;cin>>m>>n;
	long long con[1010];
	string str;cin>>str;
	cin>>d;
	int k=0;
	for(int i=m-1;i>=0;i--)
	{
	
			con[k++]=d%(str[i]-'0');
			d=d/(str[i]-'0');
	
	}

	for(int j=k-1;j>=0;j--)cout<<con[j];
	return 0;
}

三.小H的糖果

一.题目展示

小H很喜欢吃糖。

有一天,小L给小H准备了一大串糖果,它们从前往后排成一行,每个糖果上都写有一个小写字母。由于单纯的吃糖显得太单调,于是小L制定了一个规则,小H只能选择一个糖果,然后依次吃掉它和它后面的所有糖果。吃掉的这串糖果的组成的字符串字典序越大,小H的满意度就越高。然而小H可不会这么轻易地就同意小L的规则,于是据理力争来了一个条件:可以任意选择恰好一个位置,将上面的糖果替换为写有任意一个小写字母的糖果(允许替换前后的糖果上的字母相同)。

现在,聪明的你告诉小H,该如何替换糖果以及选择起始位置的糖果,得以让小H的满意度最高呢?

对于两个字符串 s1 和 s2,它们的长度分别为 n1 和 n2。定义 s1 的字典序比 s2 的小,当且仅当其满足以下两个条件之一:

  1. 如果存在一个位置 i𝑖,使得对于所有 j<i,s1,j=s2,j,而 s1,i<s2,i。即在第一个不相等的位置上,s1 的字母在字母表中的顺序靠前。
  2. 如果 s1 是 s2 的前缀,且 n1<n2。

Input

第一行输入一个 n𝑛 (1≤n≤5000) ,代表糖果的个数。

第二行输入一个字符串 s (|s|=n) ,代表糖果上字母的序列。

题目保证 s 只包含小写字母。

Output

输出共一行一个字符串,表示让小H满意度最大的糖果串。

示例一:

input

10

zzazzzabcd

output

zzzzzzabcd

示例二:

input

Copy

 

8

azzzabcd

output

zzzzbcd

二.解题思路

依次从原字符串第一个位置开始截取字符串

从截取的字符串的第一个元素开始遍历,如果是‘z’则跳过,否则改为‘z’记录这个字符串,复原,

从第二个位置截取字符串,遍历

如果是‘z’则跳过,否则改为‘z’比较记录的字符串和这个字符串,并记录较大的那个,再复原,

                   重复以上操作。

三.代码解析

for(int i=0;i<n;i++)
    {
        string b;
        b=str.substr(i);//截取子区间

    for(int k=0;k<b.size();k++)//遍历

if(b[k]=='z')continue;//是“z”跳过

b[k]='z';
          
            if(b>ma)ma=b;//记录较大的字符串

四.代码展示
      

#include<iostream>//03M-小H的糖果 
#include<string>

using namespace std;

int main()
{
	int n;
	string str,ma;
	char t;
	cin>>n>>str;ma=str;
	for(int i=0;i<n;i++)
	{
		string b;
		
		b=str.substr(i);
		
		for(int k=0;k<b.size();k++)
		{
			
		if(b[k]=='z')continue;
		else {
			t=b[k];
			b[k]='z';
	
			if(b>ma)ma=b;
			b[k]=t;
			}
		}
	}
	
	cout<<ma;
	return 0;
}


 

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/weixin_70911613/article/details/138447854

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值