CSP-X模拟赛-高乾程补题
日期:2023.10.1
学号:s08631
一:
总分数:
T1【爬楼梯(stair)】:0
T2【字符折线图(siline)】:0
T3【吉利数(lucknum)】:0
T4【路灯照明(ligting)】:0
- 比赛过程
第一题虽然简单,但是我在做的时候了,把很简单的一题想成很难,所以没得分。
第二题比较条件错了
第三天纯属蒙的,也是0分。
第四题我乱写的
- 比赛分析
T1【爬楼梯(stair)】:
1、题目大意
小可爬楼梯,爬n次,爬x阶上一层。
2、比赛中的思考
我想的是每次将n累加,超过x就请0。
- 解题思路
每次累加n,如果超过了x就把计数器清0,因为起始楼层为1,且每爬两段上一层,所以最后输出cnt/2+1
- AC代码
#include<bits/stdc++.h>
Using namespace std;
Int main(){
Int n,x,m,cnt=0,sum=0;
Cin>>n>>x;
for(int i=1;i<=n;i++){
Cin>>m;
Sum+=m;
If(sum>=x){
Cnt++;
Sum=0;
}
}
Cout<<cnt/2+1;
Return 0;
}
T2【字符折线图(siline)】:
1、
根据ascll码表来输出”/”,’\’,’-’
- 比赛中的思考
通过比较后一个来输出
- 解题思路
注意到我们会向上一行输出,这在我们程序中只使用cin, cout
等很难实现。我们可以开一个大的二维数组,以二维数组最中间的一行作为水平线,这样的话我们就可以很方便地向上或者向下一行移动。最后去掉多余的行和列,输出二维数组即可。
当然要注意细节,需要记录一下上一次的操作,从而决定行的变化。
第一个输出的要在二维数组的中间行。
第一列,之后上下变化要判断pre
。pre的变化要看if判断,如果想等的话,有两种可能,pre等于2,输出‘-’时要怎加一行,pre=3的话,输出‘-’时减一行。如果前面大,有一种,pre不等于2,输出时加一行。如果前面小,有一种可能,pre不等于3,那么输出时,要减一行。
除去多余行要通过st、en,两个变量来判断,st判断最顶上。En判断最底下的
4、AC代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
char s[105];
int g[405][405];
int main(){
scanf("%s",s);
int n=strlen(s),line=200,pre=0;
for(int i=1;i<n;i++){
if(s[i]==s[i-1]){
if(pre==2) line++;
else if(pre==3) line--;
g[line][i]=pre=1;
}
else if(s[i-1]<s[i]){
if(pre!=3) line++;
g[line][i]=pre=2;
}
else{
if(pre!=2) line--;
g[line][i]=pre=3;
}
}
for(int i=0;i<405;i++){
for(int j=204;j>0;j--){
if(g[i][j]){
g[i][0]=j;
break;
}
}
}
int bg=404,ends=0;
while(!g[bg][0]) bg--;
while(!g[ends][0]) ends++;
for(int i=bg;i>=ends;i--){
for(int j=1;j<=g[i][0];j++){
I f(!g[i][j]) printf(" ");
else if(g[i][j]==1) printf("-");
else if(g[i][j]==2) printf("/");
else printf("\\");
}
printf("\n");
}
return 0;
T3【吉利数(lucksum)】:
- 题目大意
将带有4的数字删除,输出第n个数
- 比赛思考
将所有数存进数组,把有4的删掉,接着输出a[n]
- 解题思路
将十进制转换为九进制,对于数字中大于等于 的位置,加一输出即可。
因为相当于在十进制中,去掉了 这个数字,那么就是九进制。
九进制中的 0对应十进制中的0 ,
九进制中的 1对应十进制中的1,
九进制中的2 对应十进制中的2,
九进制中的3 对应十进制中的3,
九进制中的4 对应十进制中的5,
九进制中的5 对应十进制中的6,
九进制中的6 对应十进制中的7,
九进制中的7 对应十进制中的8,
九进制中的8 对应十进制中的9,
- AC代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll t,k;
int a[30],cnt;
int main(){
scanf("%lld",&t);
while(t--){
scanf("%lld",&k);
cnt=0;
while(k){
a[cnt++]=k%9;
k/=9;
}
for(int i=cnt-1;i>=0;i--){
if(a[i]>=4) printf("%d",a[i]+1);
else printf("%d",a[i]);
}
printf("\n");
}
return 0;
}
T4【路灯照明(lingting)】:
- 题目大意
给定一个 的网格2 ∗ 2,每个网格都有一盏路灯,如果一盏路灯的耗电量是 ,则它可以为他所在的格子提供 的亮度,并且为他相邻的格子提供 ,为他对角的格子提供 的亮度,其中 表示对 向下取整。
- 比赛思考
无
- 解题思路
本题显然具有二分性,考虑二分答案。
假设总共有 的耗电量可以分配给四盏灯,我们考虑如何分配:
枚举对角线的两盏灯的耗电量,假设枚举的是 左上角 和右下角 。那么我们可以发现,右上角这个格子当前亮度为 ,左下角的格子的亮度也一样。我们可以算出这两个格子的亮度与需求的差值,再将
的耗电量分配给这两盏灯。
一种减少写代码细节的小技巧是:算出左下角格子的大致耗电量,然后用 循环在估计值的附近枚举即可,这样就不需要判断边界条件了。
- AC代码
#include <bits/stdc++.h>
#define CLOSE ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define isd(c) ('0' <= (c) && (c) <= '9')
#define isa(c) ('a' <= (c) && (c) <= 'z')
#define isA(c) ('A' <= (c) && (c) <= 'Z')
#define mem(a, b) memset(a, b, sizeof a);
#define N 100005
#define M 2000005
#define mod 1000000007
#define inf 0x3f3f3f3f
#define infll 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define PI acos(-1)
#define endl "\n"
#define pii pair<int, int>
#define F first
#define S second
#define bug cout << endl << " .....here!...." << endl;
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
int a, b, c, d;
bool check(int mid)
{
for (int i = 0; i <= a; i++)
{
for (int j = 0; j <= d; j++)
{
int need = max(a - i - j / 4, d - j - i / 4); // a,d还需要多少
If ((mid - i - j) / 2 < need)
continue;
int now = mid - i - j;
int bneed = max(0, b - i / 2 - j / 2);
int cneed = max(0, c - i / 2 - j / 2);
int bb = max(0, (bneed - now / 4) * 4 / 3);
for (int k = max(0, bb - 5); k <= min(now, bb + 5); k++)
if (k + (now - k) / 4 >= bneed && k / 4 + now - k >= cneed)
return true;
}
}
return false;
}
Int main()
{
CLOSE
cin >> a >> b >> c >> d;
int l = 0, r = a + b + c + d, ans = a + b + c + d;
while (l <= r)
{
int mid = (l + r) >> 1;
if (check(mid))
{
ans = mid;
r = mid - 1;
}
else
l = mid + 1;
}
cout << ans << endl;
}