题目描述

高桥君为了准备即将到来的7月27日土用丑日,打算邮购一些高级鳗鱼食材,通过网上银行来支付。 高桥君使用的银行卡背面有下图所示的9×9密码表。支付的时候从表中某一位置开始根据指定的方向连续读4个数字作为验证码输入,验证是否是本人操作。 下图的例子是从左边第一列,上方第一行开始,按斜右下的方向连续读4个数字。此时读出来的数字是7930.

如果读数的过程中超过了边界,就要将方向改变,然后继续读剩余的数字。改变方向的规则如下:

  • 原方向是上下左右时
  • 将原方向180°调转
  • 原方向是斜向时
  • 在对角线上时:将原方向180°调转
  • 遇到左右边界时:上下方向不变,左右方向调转
  • 遇到上下边界时:左右方向不变,上下方向调转

给出密码表、起始位置和方向,要求输出相应的4位验证码。

输入输出格式

输入格式:

  • 共10行输入
  • 第1行,整数x代表列(1≤x≤9),整数y代表行(1≤y≤9),W表示方向
  • W是R、L、U、D、RU、RD、LU、LD的其中一种
  • R:右方向
  • L:左方向
  • U:上方向
  • D:下方向
  • RU:右上方向
  • RD:右下方向
  • LU:左上方向
  • LD:左下方向
  • 第2行到第9行是密码表中的整数C[i][j](1≦i,j≦9)
  • i和j表示第i行第j列数字C[i][j]
  • Cij的范围是0到9

输出格式:

输出一行四个整数,最后输出换行。

题目分析:

这是一道模拟题。我们需要根据给出的密码本和位置读出结果。这道题看似简单,但是维护转弯操作是一个很复杂的过程。

首先在读入的时候就存在问题。读入的起始位置是先读入列后读入行,因此我设x为行,y为列,然后先输入的y后输入的x。读入密码本的时候两个数字之间并没有空格,这就使得我们不能通过直接cin的方式进行读入。我使用了scanf读入方式中的操作

scanf("%1d",&mp[i][j]);

这种操作保证了每一次只会读入一位数,避免出现连读的现象。

在读入之后我们需要维护每一个运动的方向。这里我使用的是string来存储每一个方向的名字,因为有些方向存在多个字符;然后我用了两个map来分别存储往每一个方向前进一步时,行的变化量和列的变化量。代码如下:

#include<map>
#include<string>
map<string,int>h1,h2;
int main(){
  h1["R"]=0;h2["R"]=1;h1["L"]=0;h2["L"]=-1;h1["U"]=-1;h2["U"]=0;
  h1["D"]=1;h2["D"]=0;h1["RU"]=-1;h2["RU"]=1;h1["LU"]=-1;h2["LU"]=-1;
  h1["RD"]=1;h2["RD"]=1;h1["LD"]=1;h2["LD"]=-1;
}

在初始化完每一个方向的位置变化量后要进行输出操作。一共要输出四个数,每输出一个数后进行一次位置的变化,只需要将x和y分别加上map中存储好的位置变化量即可。但是这样有可能会出现出界的问题。

为了避免出界,每一次位置的移动之后都需要对当前的位置是否在界内进行一次判断。这里只要写一个函数,判断当前x和y是否在1到9之间即可。如果不在界内则需要转弯。代码的实现如下:

 1 bool chujie(){
2 if(x<=0||x>=10||y<=0||y>=10){
3 return false;
4 }else{
5 return true;
6 }
7 }
8 int main(){
9 for(int i=1;i<=4;i++){
10 cout<<mp[x][y];
11 x+=h1[w];y+=h2[w];
12 if(chujie()==false){
13 zhuan();
14 }
15 }
16 cout<<endl;
17 return 0;
18 }

这样我们就只剩下完善转弯函数zhuan()了。

虽然运动的方向一共有8种,但是其中的向上、向下、向左、向右四种情况是很容易解决的。因为这四种情况根据题意,只需要调转方向,同时将读数位置向转后的方向倒退回去即可。

当方向为剩下四种时,情况就多样了。总的可以分为两大类,一类是撞在了四个边界上,另一类是撞在了四个对角线上。

当撞在对角线上时,根据题意,要调转方向,同时向调转后的方向倒退。这里要注意两点:第一,撞每一个对角线时撞上去的方向是固定的,绝不会出现往左下走而撞到右下角的情况,因此判断是否撞到了四个对角线的最好方式是判断坐标。第二,在判断坐标时,应当判断x和y是否等于已出界的坐标(如撞上左上角时应判断是否满足x==0&&y==0,而非x==1&&y==1),因为此时x和y已在界外。

当撞在边界上时,由于要求将原方向旋转90°,所以撞到不同边界时旋转的变化方向是不同的,因而要判断究竟撞上了哪个边界。因为已经排除了对角线的特殊情况,所以只需要判断x或y一个位置即可。判断后,每一个边界也只有两个方向能撞上,分别处理即可。

最后要注意一点,在判断以上的所有情况时都是else if,而不是if。否则会出现重复转方向问题。

最后是完整代码,注意其中的转弯函数。

 1 #include<iostream>
2 #include<map>
3 #include<cstdio>
4 #include<string>
5 using namespace std;
6 int x,y;
7 string w;
8 int mp[10][10];
9 map<string,int>h1,h2;
10 bool chujie(){
11 if(x<=0||x>=10||y<=0||y>=10){
12 return false;
13 }else{
14 return true;
15 }
16 }
17 void zhuan(){//改变方向
18 if(w=="U"){//原方向向上
19 x+=2;w="D";
20 }else if(w=="D"){
21 x-=2;w="U";
22 }else if(w=="L"){
23 y+=2;w="R";
24 }else if(w=="R"){
25 y-=2;w="L";
26 }else{
27 if(w=="LU"&&x==0&&y==0){//先处理对角线
28 x+=2;y+=2;w="RD";
29 }else if(w=="LD"&&x==10&&y==0){
30 x-=2;y+=2;w="RU";
31 }else if(w=="RU"&&x==0&&y==10){
32 x+=2;y-=2;w="LD";
33 }else if(w=="RD"&&x==10&&y==10){
34 x-=2;y-=2;w="LU";
35 }else if(y==10){//撞右边界
36 if(w=="RU"){
37 y-=2;w="LU";
38 }else if(w=="RD"){
39 y-=2;w="LD";
40 }
41 }else if(y==0){//撞左边界
42 if(w=="LU"){
43 y+=2;w="RU";
44 }else if(w=="LD"){
45 y+=2;w="RD";
46 }
47 }else if(x==0){//撞上边界
48 if(w=="LU"){
49 x+=2;w="LD";
50 }else if(w=="RU"){
51 x+=2;w="RD";
52 }
53 }else if(x==10){//撞下边界
54 if(w=="RD"){
55 x-=2;w="RU";
56 }else if(w=="LD"){
57 x-=2;w="LU";
58 }
59 }
60 }
61 }
62 int main(){
63 cin>>y>>x>>w;//x是行,y是列
64 for(int i=1;i<=9;i++){
65 for(int j=1;j<=9;j++){
66 scanf("%1d",&mp[i][j]);
67 }
68 }
69 h1["R"]=0;h2["R"]=1;h1["L"]=0;h2["L"]=-1;h1["U"]=-1;h2["U"]=0;
70 h1["D"]=1;h2["D"]=0;h1["RU"]=-1;h2["RU"]=1;h1["LU"]=-1;h2["LU"]=-1;
71 h1["RD"]=1;h2["RD"]=1;h1["LD"]=1;h2["LD"]=-1;
72 for(int i=1;i<=4;i++){
73 cout<<mp[x][y];
74 x+=h1[w];y+=h2[w];
75 if(chujie()==false){
76 zhuan();
77 }
78 }
79 cout<<endl;
80 return 0;
81 }

AT212 P-CASカードと高橋君的更多相关文章

  1. 高橋君とホテル / Tak and Hotels

    高橋君とホテル / Tak and Hotels Time limit : 3sec / Stack limit : 256MB / Memory limit : 256MB Score : 700  ...

  2. 高橋君とカード / Tak and Cards

    高橋君とカード / Tak and Cards Time limit : 2sec / Stack limit : 256MB / Memory limit : 256MB Score : 300 p ...

  3. AT987 高橋君

    AT987 高橋君 给出 \(n,\ k\) ,求 \(\displaystyle\sum_{i=0}^kC_n^k\) , \(T\) 次询问 \(T\leq10^5,\ 0\leq k\leq n ...

  4. 高橋君とカード / Tak and Cards AtCoder - 2037 (DP)

    Problem Statement Tak has N cards. On the i-th (1≤i≤N) card is written an integer xi. He is selectin ...

  5. AtCoder Beginner Contest 044 C - 高橋君とカード / Tak and Cards

    题目链接:http://abc044.contest.atcoder.jp/tasks/arc060_a Time limit : 2sec / Memory limit : 256MB Score ...

  6. AtCoder Beginner Contest 044 A - 高橋君とホテルイージー / Tak and Hotels (ABC Edit)

    Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement There is a hotel with ...

  7. 【AT987】高橋君

    题目 成爷爷一眼秒,\(tql!!!\) 多组询问,求 \[\sum_{i=0}^kC_{n}^i \] 发现\(k<=n\)啊,于是我们可以把一组询问抽象成一个区间\([k,n]\) 左指针的 ...

  8. AtCoder D - 高橋君と見えざる手 / An Invisible Hand 简单思维题

    http://arc063.contest.atcoder.jp/tasks/arc063_b 因为每次都是选取最大值,那么用dp[i]表示第i个数结尾能得到最大是多少. 其实就是用a[i]去减去左边 ...

  9. AtCoder Beginner Contest 022 A.Best Body 水题

    Best Body Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://abc022.contest.atcoder.jp/tasks/abc02 ...

  10. AtCoder-arc060 (题解)

    A - 高橋君とカード / Tak and Cards (DP) 题目链接 题目大意: 有 \(n\) 个数字,要求取出一些数字,使得它们的平均数恰好为 \(x\) ,问有几种取法. 大致思路: 只要 ...

随机推荐

  1. elasticsearch组件

    elasticsearch组件 Elasticsearch 是一个实时的分布式搜索分析引擎,它能让你以前所未有的速度和规模,去探索你的数据. 它被用作全文检索.结构化搜索.分析以及这三个功能的组合 E ...

  2. CAD中如何将图形对象转换为三维实体?

    有些小伙伴在CAD绘制完图纸后,想要将图纸中的某些图形对象转换成三维实体,但却不知道该如何操作,其实很简单,本节CAD绘图教程就和小编一起来了解一下浩辰CAD软件中将符合条件的对象转换为三维实体的相关 ...

  3. (K8s学习笔记四)常用命令实例

    1.显示Pod的更多信息 kubectl get pod <pod-name> -o wide kubectl get pods -show-all # 查看已经停止的Pod 2.以yam ...

  4. elasticSearch(四)--结构化查询

    结构化查询 1.请求体查询 GET(POST) /_search POST /_search { "from": 30, "size": 10 } 2.DSL ...

  5. Java语言出现的背景、影响及应用前景分析

    一.背景 1991年 ,SUN MicroSystem公司的 Jame Gosling. Bill Joe等人 ,为在电视.控制烤面包箱等家用消费类电子产品上进行交互式操作而开发了一个名为Oak的软件 ...

  6. ubuntu20.0.4 安装influxdb

    官网:https://docs.influxdata.com/influxdb/v2.3/install/?t=Linux1.命令:# Ubuntu/Debian wget https://dl.in ...

  7. H5 判断当前浏览器环境是 微信还是支付宝

    let ua = window.navigator.userAgent.toLowerCase(); //判断是不是微信 if (ua.match(/MicroMessenger/i) == &quo ...

  8. Access denied You do not have access to chat.openai.com. The site owner may have set restrictions that prevent you from accessing the site.解决办法

    报错 Access denied You do not have access to chat.openai.com. The site owner may have set restrictions ...

  9. java中对list集合进行分组

    java中对list集合进行分组 Map<String, List<HealthImport>> excelIdCardNull = importList.stream() . ...

  10. TypeScript 对象

    TypeScript 对象 对象是包含一组键值对的实例. 值可以是标量.函数.数组.对象等,如下实例: var object_name = { key1: "value1", // ...