OneCode(天梯五) 总结

本文解析了四个算法题目,包括小数处理、俄罗斯方块消除策略、矩阵元素验证及未知寻宝游戏。提供了详细的解题思路与源代码,涵盖了字符串处理、贪心算法、枚举方法等知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A:六舍七入               10/20;

B:俄罗斯方块           10/20;

C:月份矩阵               2/20;

D:杜拉拉寻宝           19/20.

A:

{

此题的思路不算难想,就是复杂了点(本人1A)

思路如下:
此题数据中可能含有小数点和符号,所以不适宜直接读入,可以使用读入到char或string类型里

本人对此还附加了把char里的数字读入到int类型的mapn数组里的操作,负号另开变量记录,小数点用-2表示

接着for循环搜索小数点的位置,记录到poi里

得到poi的值,进行一次分类讨论:
1,是否不存在小数部分(直接输出,并加上“.00”)

2,是否小数部分只有两位(直接输出)

3,否则继续执行下面代码

接下来的代码需要处理的数据都是正常的了,之所谓正常者,小数点后多于三位也

好似123.997和-342.11678一样

当然,“六舍七入”至小数点后两位和“四舍五入”至小数点后两位其实是一样的道理,真正重要的是千分位,再往后的都和答案没关系

接下来用if判断千分位是否大于等于7,是就进一,否就输出千分位以前的值

如果进一了,那么需要一个for循环从后往前像数学上的一样传递进一后的影响(需要注意跳开小数点和对最高位的进一处理)

for循环结束后,进行的就是输出环节

首先,判断是否有符号,有就输出

接着把整数位的0删除到只剩一个

最后输出主体,当然,千分位以后的就不用输出了

That‘s all.It's easy,isn't it?

接下来给出本人的程序(可能和以上讲的略有不同):

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

using namespace std;
int n;
char ch[1100];
int mapn[1100];
int work()
{
    memset(mapn,0,sizeof(mapn));
    cin>>ch;
    int zf=1;
    int poi=-1;
    int l=strlen(ch);
    for(int i=1;i<=l;i++)
    {
        if(ch[i-1]=='.') mapn[i]=-1,poi=i;
            else
            if(ch[i-1]=='-') zf=0,mapn[i]=0;
                else mapn[i]=ch[i-1]-'0';
    }
    if(poi==-1)
    {
        cout<<ch<<".00"<<endl;return 0;
    }
    if(poi==l-2)
    {
        cout<<ch<<endl;return 0;
    }
    int nl=poi+2;
    if(mapn[nl+1]>=7) mapn[nl]+=1;
    if(mapn[nl]>=10)
    {
        for(int i=nl;i>=1;i--)
        {
            if(mapn[i]>=10)
            {
                int t=1;
                if(mapn[i-1]==-1) t=2;
                mapn[i-t]+=mapn[i]/10;
                mapn[i]%=10;
            }
        }
    }
    if(mapn[0]!=0) cout<<mapn[0];
    
    int b=1; if(mapn[b]==0) b=2;
    
    if(!zf) cout<<'-';
    
    if(poi-1<b) cout<<0;
    
    for(int i=b;i<=nl;i++)
    {
        if(mapn[i]>=0) cout<<mapn[i];
        else cout<<'.';
    }
    cout<<endl;
}
int main()
{
    cin>>n;
    for(int d=1;d<=n;d++)
    {
        work();
    }
    return 0;
}

最后注意,由于是多组数据,所以要记得初始化哦~
}

B:

{

本题也不算太难,主要要找对策略(贪心)(1A)

读题可以发现,删除方块的方法有两种截(横向删除)和斩(纵向删除)

可以看出横向删除是群伤,而纵向删除是个体伤害

当数据多时,横向删除其实是最划算的

所以应该尽量进行横向删除,剩下的再使用纵向删除

得出解法:

使用for循环从开头截去i行(0<=i<=最大值),其余方块则斩掉的情况

并记录下所用步数,最后输出最小值

没错,就是这么简单……

给出程序如下:

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>

using namespace std;
int t;
int mapn[10000001];
int work()
{
    int ans=9999,m=-1,n;
    cin>>n;int peo=n;
    for(int i=1;i<=n;i++)
    {
        cin>>mapn[i];m=max(m,mapn[i]);
    }
    
    for(int i=0;i<=m;i++)
    {
        peo=i;
        for(int j=1;j<=n;j++)
        if(mapn[j]>i) peo++;
        ans=min(ans,peo);
    }
    cout<<ans<<endl;
}
int main()
{
    cin>>t;
    for(int d=1;d<=t;d++)
    {
        work();
    }
    return 0;
}

需要注意循环横向删除时循环的范围哦(上文已给出)~
}

C:
{

太简单了,枚举,肯定不会超时的

给出本人程序,当然是使用比较特殊的操作的:

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>

using namespace std;
int t,n,m;
int mapn[3033][3033];
int work()
{
    memset(mapn,-1,sizeof(mapn));
    int k=0;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    {
        cin>>mapn[i][j];
        if(mapn[i-1][j]==mapn[i][j]||mapn[i][j-1]==mapn[i][j])    k=1;
    }
    if(k) cout<<"WRONG"<<endl;
    else cout<<"RIGHT"<<endl;
    return 0;
}
int main()
{
    cin>>t>>n>>m;
    for(int d=1;d<=t;d++)
    {
        work();
    }
}


}

D:
{

并没看懂题目,自然也没有AC

但给出一点提示,但愿你能打破无人AC的窘境

如下:

[提示图片]

    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值