0
点赞
收藏
分享

微信扫一扫

新手入门刷题(专题一)模拟与高精度(第二部分)———>持续更新

RJ_Hwang 2022-04-05 阅读 24
c++算法

某csdn大佬推荐的新手刷题网站,快速入门!洛谷

新手入门刷题(专题一)模拟与高精度(第二部分)———>持续更新


4月4日

[USACO2.4]两只塔姆沃斯牛 The Tamworth Two

题目描述

略,见题目链接

思路

无解的情况:

当牛和人同时再次出现在之前走过的地方,且牛和人的方向相同时,判断为无解

bool len[2000000];
//牛x+牛y*10+牛方向*100+人x*1000+人y*10000+人方向*100000,唯一值
int st = (x_c-1) + (y_c-1)*10 + (x_f-1)*100 + (y_f-1)*1000 + f_c * 10000 + f_f *100000;
if(!len[st]) len[st] = true;
else{
    cout<<0;
    return 0;
}

代码

#include<iostream>
#include<cstring>
using namespace std;
bool len[2000000];
//把移动单独拎出来
void move(int &flag,char a[][12],int &x,int &y){
    //先判断方向,再判断该方向下一步是否为障碍物
    //上
    if(flag==0&&a[x-1][y]!='*'){
        char t = a[x-1][y];
        a[x-1][y] = a[x][y];
        a[x--][y] = t; 
    //右
    }else if(flag==1&&a[x][y+1]!='*'){
        char t = a[x][y+1];
        a[x][y+1] = a[x][y];
        a[x][y++] = t; 
    //下
    }else if(flag==2&&a[x+1][y]!='*'){
        char t = a[x+1][y];
        a[x+1][y] = a[x][y];
        a[x++][y] = t; 
    //左
    }else if(flag==3&&a[x][y-1]!='*'){
        char t = a[x][y-1];
        a[x][y-1] = a[x][y];
        a[x][y--] = t; 
    //转向
    }else flag = (flag+1)%4;
}
int main(){
    //数组多两行两列,使其边界全是障碍物
    char a[12][12],b[12][12];
    memset(a,'*',12*12);
    memset(b,'*',12*12);
    int x_c,x_f,y_c,y_f;
    //牛和人分开到两个数组,防止出现人牛无限循环
    for(int i=1;i<=10;i++){
        for(int j=1;j<=10;j++){
            cin>>a[i][j];
            //a数组放牛,b数组放人
            a[i][j]=='C'?b[i][j]='.':b[i][j]=a[i][j];
            if(a[i][j]=='F') a[i][j]='.';
            if(a[i][j]=='C') x_c=i,y_c=j;
            if(b[i][j]=='F') x_f=i,y_f=j;
        }
    }
    int f_c,f_f,times;
    f_c=f_f=times=0;
    while(1){
        int st = (x_c-1) + (y_c-1)*10 + (x_f-1)*100 + (y_f-1)*1000 + f_c * 10000 + f_f *100000;
        //如果人和牛走到原来的路和原来的方向,循环结束,判断为误解
        if(!len[st]) len[st] = true;
        else{
             cout<<0;
             return 0;
        }
        move(f_c,a,x_c,y_c);
        move(f_f,b,x_f,y_f);
        times++;
        //如果人和牛的定位相同,循环结束,输出步数
        if(x_c==x_f&&y_c==y_f){
            break;
        }
    }
    cout<<times;
	return 0;
}  

[NOIP2009 普及组] 多项式输出

题目描述

模拟一元多项式(第二个觉得简单的题目),详见题目链接

思路

考虑三个方面:系数、次方、常数

系数为零,多项式正负号,系数为正负1时

次方大于1以及等于1的情况

前有多项式时,常数正负号,以及常数为0

前无多项式时,常数正负号,以及常数为0

代码

#include<iostream>
using namespace std;
int main(){
    int a;
    cin>>a;
    int b[a+1];
    for(int i=0;i<a+1;i++){
        cin>>b[i];
    }
    int t = a;
    //处理到常数之前
    for(int i=0;i<a;i++){
        //系数为0,只执行次方递减,
        if(b[i]==0){
            t--;
            continue;
        }
        //系数为正数且不为第一个数时添加加号
        if(b[i]>0&&i!=0) cout<<'+';
        //系数不为1或-1时输出系数
        if(b[i]*b[i]!=1) cout<<b[i];
        //系数为-1时输出负号
        if(b[i]==-1) cout<<'-';
        //次方大于1时显示自变量x和次方t
        if(t>1) cout<<"x^"<<t;
        //次方等于1时只显示自变量x
        if(t==1) cout<<"x";
        t--;
    }
    //常数单独拎出来
    //只有常数直接输出
    if(a==0) cout<<b[a];
    //前有自变量x,判断常数正负号以及是否为零
    else if(b[a]>0) cout<<'+'<<b[a];
    else if(b[a]<0) cout<<b[a];
    
}

4月5日

[NOIP2007 提高组] 字符串的展开

题目描述

将字符串折叠部分按规则展开,详见题目链接

思路

首先要考虑什么情况需要展开,比如 a-z、0-9、a-b、0-1等情况需要展开

什么情况不能展开,比如 -sdxva55、as35-、a-0、0-a、—、0-0、a-a、z-a、9-0等情况无需展开

其次对展开步骤进行分析

先考虑大写情况,只有字母展开需要大写,因此当规则为大写时,只分析字母就行;

接着,无论是大写情况下的数字,还是小写情况下的字母或数字,可以放一起考虑;

最后是*情况,这种情况比较简单

重复情况直接在输出时叠加for循环即可

逆序或顺序放在最外层考虑。

关于代码中的疑点,a[i+1] - a[i-1] < 26,因为字符 a - z 最大情况为 26,0 - 9 最大情况为 10,具体可查看ascii码表,但是有一种情况也满足 a[i+1] - a[i-1] < 26 ,那就是 - - 0 ,- 的 ascii 码为 45 ,0 的 ascii 码为 48 ,因此二者相减也小于26,但是这种情况是不能展开的,故当 a[i-1] ! = ‘-’。

代码

#include<iostream>
using namespace std;
char a[100000];
//展开操作
int ext(char a,char c,int x,int y,int z){
    //正序展开
    if(z==1){
        //转成大写的情况
        if(x==2&&'a'<=a&&a<='z'&&'a'<=c&&c<='z'){
            for(char i=a-31;i<c-32;i++){
                for(int j=0;j<y;j++){
                    cout<<i;
                }
            }
        //不用转成大写的情况
        }else if(x==1||x==2){
            for(char i=a+1;i<c;i++){
                for(int j=0;j<y;j++){
                    cout<<i;
                }
            }
        //转成*的情况
        }else{
            for(char i=a+1;i<c;i++){
                for(int j=0;j<y;j++){
                    cout<<'*';
                }
            }
        }
    //逆序展开
    }else if(z==2){
        //转成大写的情况
        if(x==2&&'a'<=a&&a<='z'&&'a'<=c&&c<='z'){
            for(char i=c-33;i>=a-31;i--){
                for(int j=0;j<y;j++){
                    cout<<i;
                }
            }
        //不用转成大写的情况
        }else if(x==1||x==2){
            for(char i=c-1;i>=a+1;i--){
                for(int j=0;j<y;j++){
                    cout<<i;
                }
            }
        //转成*的情况
        }else{
            for(char i=c-1;i>=a+1;i--){
                for(int j=0;j<y;j++){
                    cout<<'*';
                }
            }
        }
    }
    
}
int main(){
    int p1,p2,p3;
    cin>>p1>>p2>>p3;
    char t;
    int la=0;
    while(cin>>t) a[la++]=t;
    for(int i=0;i<la;i++){
        //当'-'不在头和尾、且'-'的前一位<'-'的后一位、且后一位减去前一位小于26、且前一位不是'-'时才能展开
        if(a[i]=='-'&&i!=0&&i!=la-1&&a[i-1]<a[i+1]&&a[i+1]-a[i-1]<26&&a[i-1]!='-'){
            ext(a[i-1],a[i+1],p1,p2,p3);
        }else{
            cout<<a[i];
        }
    }
}
举报

相关推荐

0 条评论