NCST 2018-2019秋季学期个人排位赛(三)

10 篇文章 2 订阅

NCST 2018-2019秋季学期个人排位赛(三)

A:养生茶的制作
题目描述:

F学长是一个非常懂得生活的人,平时喜欢制作一些养生的物品,这天F学长正在根据自己的机密配方制作养生茶,其中有两种配料’|‘和’&‘有着严格的添加顺序,必须先添加完’|‘后才能再添加’&’,只有这样两种材料才会融合,其他任何方式的添加都不能使材料融合(也可以完全不加这两种材料),如两种材料不能融合那么就是一种错误的制作方法,现在给你一些制作方法,请你判断这些方法是正确的还是错误的

输入:

一个数n表示有n组数据

每组数据由一个字符串组成,长度小于50

输出:

Yes或No

样例输入:
4
&FXZWD!!!|
|FXZNB!!!&
||NCSTOJ&
|&|&|&|&|&
样例输出:
No
Yes
No
Yes

题目原型:括号匹配,方法用遇到‘|’用栈保存,遇到‘&’时,如果栈空,那么就是非法, 不空就弹出元素,读取完成后判断栈中是否有元素就可以了。

类似于“(())”也就是本题的“||&&”也是正确的答案,因为匹配对应问题的融合

#include<cstring>
#include<cstdio>
#include<stack>
#define rep(i,a,b) for(int i=(a); i<(int)(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(int)(b);++i)
using namespace std;

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        char c[50];
        int flag=0;
        scanf("%s",c);
        stack<char> s;
        rep(i,0,strlen(c))
        {
            if(c[i]=='|')
                s.push(c[i]);//入栈
            if(c[i]=='&')
            {
                if(s.empty())
                {
                    flag=1;
                    printf("No\n");
                    break;
                }
                s.pop();//出栈
            }
        }
        if(flag)
            continue;
        if(s.empty())
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}
B:TIO的得分
题目描述:

给出n个由T,I和O组成的字符串,长度小于50,统计所有字符的得分和,每个O的得分为目前连续出现的O的个数,每个I得两分而且不累计,T的得分为0分。

例如:OTITOOOTITOIIT的得分为1+0+2+0+1+2+3+0+2+0+1+2+2+0=16分

输入:

一个数n,表示有n组数据

接下来n行,每行一个字符串

输出:

n行,每行为字符串的得分

样例输入:
1
OTITOOOTITOIIT
样例输出:
16

算法竞赛入门经典P57例题3-1改(UVa1585)

做一个临时变量和总分变量,根据遇到的字母改变就可以

ps:坑了一把else少写了个t=0,结果数据全错了,自责

#include<cstdio>
#include<cstring>
#define rep(i,a,b) for(int i=(a); i<(int)(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(int)(b);++i)
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        char c[100];
        int sum=0,t=0;
        scanf("%s",c);
        rep(i,0,strlen(c))
        {
            if(c[i]=='T')
                t=0;
            else if(c[i]=='O')
            {
                ++t;
                sum+=t;
            }
            else
            {
                sum+=2;
                t=0;
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}
C:除法
题目描述:

输入正整数n,从小到大输出所有形如 a b c d e f g h i j \frac{abcde}{fghij} fghijabcde=n的表达式,其中a ~ j恰好为数字0 ~ 9的一个排列(可以有前导0), 2 ≤ n ≤ 79 2\le n \le79 2n79

输入:

n

n为0时表示输入结束

输出:

每种可能的情况,顺序为abcde从小到大输出

形式如: xxxxx/xxxxx=n

如果没有满足的等式,输出There are no solutions

样例输入:
61
62
0
样例输出:
There are no solutions
79546/01283=62
94736/01528=62

算法竞赛入门经典P182例题7-1(UVa725)

认真分析问题下暴力法也是很快的,首先肯定不能用除法来算,所有的除法都要转化为乘法。先来分析分母,因为可以有前导0所以fghij从1234开始循环,然后abcde可以根据n来乘出来,那么循环结束的条件是什么,a-j为0-9的全排列,最多10个数,当两个数的位数加起来超过10位那么循环就可以终止了

ps:这题本来是想出火柴棍 的,因为我不知道啊哈上面有这个题,不过在我就要加题之前yk同学问我这个题,我很是mb,才发现啊哈上有这个题

这里再给一个题

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
    int n,mc;
    char buf[99];
    while(scanf("%d",&n)==1&&n)
    {
        int cnt=0;
        for(int fghij=1234;;++fghij)
        {
            int abcde=fghij*n;
            sprintf(buf,"%05d%05d",abcde,fghij);    //%05d,位数不足补0
            if(strlen(buf)>10)
                break;
            sort(buf,buf+10);
            int flag=1;
            for(int i=0;i<10;++i)//判断0-9是否全部被使用过
                if(buf[i]!='0'+i)
                    flag=0;
            if(flag)
            {
                ++cnt;
                printf("%05d/%05d=%d\n",abcde,fghij,n);
            }
        }
        if(!cnt)
            printf("There are no solutions\n");
    }
    return 0;
}
D:素数环
题目描述:

输入正整数n,把整数1,2,. . . ,n组成一个环(每组第一个数都是1),使得相邻的两个整数之和均为素数。一个环恰好输出一次。 n ≤ 16 n\le16 n16

多组数据,读入EOF结束

输入:

n

输出:

所有情况

第i组数据输出时加上一行Case i:

每一行最后一个数后没有空格

相邻两组数据之间加上空行

祥见样例

样例输入:
6
8
样例输出:
Case 1:
1 4 3 2 5 6
1 6 5 2 3 4

Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2

算法竞赛入门经典P194例题7-4(UVa524)

标准DFS标准DFS标准DFS!!!!!!!!!!!

因为数小,普通的素数判断就可以了,如果数大那么判断素数的时间复杂度也是需要考虑的,这里用的是埃拉托色尼(Eratosthenes)筛法,直接可以标识一个数是不是素数

next_permutation也过不了

#include<cstdio>
#include<math.h>
#include<string.h>
const int maxn=50;
int vis[maxn];
int n,pr[20],book[20];

void prime()
{
    int m=sqrt(maxn+0.5);
    for(int i=2;i<m;++i)
        if(!vis[i])
            for(int j=i*i;j<=maxn;j+=i)
                vis[j]=1;//代表j不是素数
}

bool isPrime(int n)
{
    return vis[n]?false:true;
}

void dfs(int cur)
{
    if(cur==n&&isPrime(pr[0]+pr[n-1]))
    {
        for(int i=0;i<n;++i)
            printf("%d%c",pr[i]," \n"[i==n-1]);
        return;
    }
    for(int j=2;j<=n;++j)
    {
        if(!book[j]&&isPrime(j+pr[cur-1]))//这里剪枝
        {
            pr[cur]=j;
            book[j]=1;
            dfs(cur+1);
            book[j]=0;
        }
    }
}

int main()
{
    prime();
    int tot=0;
    while(scanf("%d",&n)==1)
    {
        memset(book,0,sizeof(book));
        if(tot)
            printf("\n");
        ++tot;
        printf("Case %d:\n",tot);
        pr[0]=1;
        dfs(1);
    }
    return 0;
}
E:F学长的养生茶!!!
题目描述:

F学长刚刚制作好的养生茶被坏同学偷偷的放在了迷宫里的一个地方。迷宫用 N × M N \times M N×M的矩阵表示( N , M ≤ 100 N,M\le 100 N,M100)矩阵中的每项可以代表道路(’@’),墙壁(’#’)和高数题(‘x’)

年轻的F学长(‘r’)决定去寻找他的养生茶(‘a’),由于坏同学在路上放了很多高数题,F学长必须解决高数题后才能继续前进,每移动一个位置需要花费1个单位时间,做出一道高数题也需要1个单位时间,同时F学长非常聪明,能做出所有的高数题

给定迷宫,养生茶,F学长和高数题的位置,计算找到养生茶所需要的最短时间

输入:

第一行n,表示有n组数据

每组数据有n,m,代表迷宫行和列

迷宫中’@'代表道路,'a’代表养生茶,'r’代表F学长,‘x’代表高数题,’#'代表墙壁

输出:

如果F学长能找到他的养生茶,输出行动所需最短时间,否则输出Impossible

样例输入:
1
7 8
#@#####@
#@a#@@r@
#@@#x@@@
@@#@@#@#
#@@@##@@
@#@@@@@@
@@@@@@@@
样例输出:
13

改编自 ,这个题可以让你对BFS有更深一点的理解

1
6 5
#####
#@r@#
#@x@#
#@x@#
#@x@#
#@a@#

根据这个数据理解一下路径最短和时间最短,有高数题的点要理解成走两次

#include<queue>
#include<cstdio>
#include<cstring>
#define rep(i,a,b) for(int i=(a); i<(int)(b);++i)
using namespace std;

const int dir[4][2]={0,1,1,0,0,-1,-1,0};
int n,m,book[205][205];
char maze[205][205];

struct point
{
    int r,c;
    int step;
    point(int r=0,int c=0,int step=0):r(r),c(c),step(step){}
};

point tar,start;
void bfs()
{
    queue<point> q;
    q.push(start);
    book[start.r][start.c]=1;
    point now;
    while(!q.empty())
    {
        now=q.front();
        int now_r=now.r;
        int now_c=now.c;
        if(now_r==tar.r&&now_c==tar.c)
        {
            printf("%d\n",now.step);
            return;
        }
        q.pop();
        if(maze[now_r][now_c]=='x')//遇到高数题
        {
            maze[now_r][now_c]='@';//走到这个位置后再解决高数题
            q.push(point(now_r,now_c,now.step+1));
        }
        else
            rep(k,0,4)
            {
                int next_r=now_r+dir[k][0];
                int next_c=now_c+dir[k][1];
                if(next_r>=0&&next_r<n&&next_c>=0&&next_c<m
                &&!book[next_r][next_c]&&maze[next_r][next_c]!='#')
                {
                    book[next_r][next_c]=1;
                    q.push(point(next_r,next_c,now.step+1));//走到当前位置,是不是高数题无所谓
                }
            }
    }
    if(q.empty())
        printf("Impossible\n");
}

void input()
{
    rep(i,0,n)
    {
        scanf("%s",maze[i]);
        rep(j,0,m)
        {
            if(maze[i][j]=='a')
                tar=point(i,j,0);
            if(maze[i][j]=='r')
                start=point(i,j,0);
        }
    }
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        memset(book,0,sizeof(book));
        input();
        bfs();
    }
    return 0;
}

或者直接用优先队列,如果情况更复杂的话上述分情况加点的方法就不是很好实现了,比如我有各种不同的题,每种题需要的时间也不同,那么这样就只能用优先队列了

现在再回看入门经典那个倒水问题才知道有很多的重点和易错点,这题属于倒水问题的入门
又和F学长学一招,检查状态时先检查位置是否越界再检查数组的状态,因为如果位置越界了那么数组可能会访问到非法内存,越严谨越好

#include<queue>
#include<cstdio>
#include<cstring>
#define rep(i,a,b) for(int i=(a); i<(int)(b);++i)
using namespace std;

const int dir[4][2]={0,1,1,0,0,-1,-1,0};
int n,m,book[205][205];
char maze[205][205];

struct point
{
    int r,c;
    int step;
    bool operator < (const point& a)const//用时小的点先出队
    {
        return step>a.step;
    }
    point(int r=0,int c=0,int step=0):r(r),c(c),step(step){}

};

point tar,start;
void bfs()
{
    priority_queue<point> q;
    q.push(start);
    book[start.r][start.c]=1;
    while(!q.empty())
    {
        point now=q.top();
        int now_r=now.r;
        int now_c=now.c;
        if(now_r==tar.r&&now_c==tar.c)
        {
            printf("%d\n",now.step);
            return;
        }
        q.pop();
        rep(k,0,4)
        {
            int next_r=now_r+dir[k][0];
            int next_c=now_c+dir[k][1];
            if(next_r>=0&&next_r<n&&next_c>=0&&next_c<m
                &&!book[next_r][next_c]&&maze[next_r][next_c]!='#')
            {
                book[next_r][next_c]=1;
                if(maze[next_r][next_c]=='x')
                    q.push(point(next_r,next_c,now.step+2));
                else
                    q.push(point(next_r,next_c,now.step+1));
            }
        }
    }
    if(q.empty())
        printf("Impossible\n");
}

void input()
{
    rep(i,0,n)
    {
        scanf("%s",maze[i]);
        rep(j,0,m)
        {
            if(maze[i][j]=='a')
                tar=point(i,j,0);
            if(maze[i][j]=='r')
                start=point(i,j,0);
        }
    }
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        memset(book,0,sizeof(book));
        input();
        bfs();
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
帮我看一下这段代码有什么问题 clear all; fname='G:\CMIP6 data\map_hed\ACCESS-CM2\ssp126.xlsx'; [data]=xlsread(fname); lat = ncread('G:\CMIP6 data\CMIP6_china\Precipitation\ACCESS-CM2 (Australia)\pr_day_ACCESS-CM2_ssp126_r1i1p1f1_gn_20150101-21001231_v20191108.nc','lat'); lon = ncread('G:\CMIP6 data\CMIP6_china\Precipitation\ACCESS-CM2 (Australia)\pr_day_ACCESS-CM2_ssp126_r1i1p1f1_gn_20150101-21001231_v20191108.nc','lon'); % [x,y]=meshgrid(lon,lat); filename4=('E:\XB\xibei\NewFolder\xeibei84.shp'); Shape=shaperead(filename4); Sx=Shape.X;Sy=Shape.Y; R=m_shaperead('E:\XB\xibei\xb_wang');clf; close all a=find(lon>=70 & lon<=140); b=find(lat>=20 & lat<=60); lon_num=length(a);lat_num=length(b); lonn=lon(a,:);latt=lat(b,:); % D=num2cell(data); for i=1 for g=1:length(lon); x=lon(g); for h=1:length(lat); y=lat(h); U=inpolygon(x,y,Sy,Sx); if U==0 data(g,h,:)=nan; end end end end set(gcf,'Position',[0.1 0.1 1500 1000]); [X,Y]=meshgrid(lonn,latt);hold on; m_proj('miller','lon',[70 110],'lat',[30 50]); uu=m_pcolor(X,Y,data'); shading interp; set(uu,'edgecolor','none') % m_grid('linewi',2,'linest','none','xtick',[70:5:115],'ytick',[30:5:50],'fontsize',22,'linewidth',2); % WBGYR % colorbar % h=colorbar('eastoutside'); colormap('autumn'); colorbar; % set(h,'ticks',[-0.1:0.05:0.3],'linewidth',2,'fontsize',22); % caxis([-0.1 0.3]); for v=1:length(R.ncst) m_line(R.ncst{v}(:,1),R.ncst{v}(:,2),'Color','k','Linewidth',0.5); end hold on; % title(' ','fontsize',25); % saveas(figure(1),'spatial.tif') % close all %
06-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值