Loading

题目---汉诺塔及AI代码及八皇后

2019春第十一周作业

 

这个作业属于那个课程 C语言程序设计II
这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/software-engineering-class2-2018/homework/3201
我在这个课程的目标是 熟悉经典数论
这个作业在那个具体方面帮助我实现目标 递归函数及数论
参考文献 算法入门经典,基础数论i,ii,iii

 

 

  本周题目难度算目前以来难度最高的一次了,反正的我是枯了,写了很久才写出来,咱也不敢问,咱也不知道为什么。

 

 选择题

 

2-1

宏定义“#define DIV(a, b) a/b”,经DIV(x + 5, y - 5) 引用,替换展开后是()。 (1分)

作者: 张高燕
单位: 浙江大学城市学院
2-2

定义带参数的宏“#define JH(a,b,t) t = a; a = b; b = t”,对两个参数a、b的值进行交换,下列表述中正确的是()。 (1分)

作者: 张高燕
单位: 浙江大学城市学院
2-3

如果所有的变量按照下面的程序进行定义和声明,那么在main()函数中所有可用的变量为 ()。 (2分)

void fun(int x)
{  
    static int y;
    ……
    return;
}
int z;
void main( )
{   
    int a,b;
    fun(a);
    ……
}
作者: 李克峰
单位: 山东交通学院
2-4

如果一个变量在整个程序运行期间都存在,但是仅在说明它的函数内是可见的,这个变量的存储类型应该被说明为( )。 (1分)

作者: 王从银
单位: 吉首大学
2-5

下面说法中正确的是()。 (1分)

作者: 张高燕
单位: 浙江大学城市学院
2-6

凡是函数中未指定存储类别的局部变量,其隐含的存储类型为( )。 (1分)

作者: 张高燕
单位: 浙江大学城市学院
2-7

在一个C源程序文件中,若要定义一个只允许本源文件中所有函数使用的全局变量,则该变量需要使用的存储类别是。 (1分)

作者: 张高燕
单位: 浙江大学城市学院
2-8

将一个函数说明为static后,该函数将 ( )。(1分)

作者: 张高燕
单位: 浙江大学城市学院
 

 

编程题:

 

  第一题:

  

7-1 汉诺塔问题* (10 分)

 

汉诺塔是一个源于印度古老传说的益智玩具。据说大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘,大梵天命令僧侣把圆盘移到另一根柱子上,并且规定:在小圆盘上不能放大圆盘,每次只能移动一个圆盘。当所有圆盘都移到另一根柱子上时,世界就会毁灭。

题图1.jpg

请编写程序,输入汉诺塔圆片的数量,输出移动汉诺塔的步骤。

输入格式

圆盘数 起始柱 目的柱 过度柱

输出格式

移动汉诺塔的步骤
每行显示一步操作,具体格式为:
盘片号: 起始柱 -> 目的柱
其中盘片号从 1 开始由小到大顺序编号。

输入样例

3
a c b

输出样例

1: a -> c
2: a -> b
1: c -> b
3: a -> c
1: b -> a
2: b -> c
1: a -> c
 

 

实验代码:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 void solve(int n , char a , char b , char c)
 5 {
 6     if (n == 1)cout << n << ": " << a << " -> " << c << endl;
 7     else{
 8         solve(n - 1, a, c, b);cout << n << ": " << a << " -> " << c <<endl;solve(n - 1, b, a, c);}
 9 }
10 
11 int main(int argc, const char * argv[])
12 {
13     int n;
14     char A, B, C;
15     cin >> n;
16     cin >> A >> B >> C;
17     solve(n, A, C, B);
18     
19     return 0;
20 }

 

设计思路

 

本题调试过程中遇到的问题及解决方法

汉诺塔问题是一道经典的递归题,一开始过渡柱和目的柱交换过程出错,及时改回。

 

运行结果截图

 

 

第二题

7-2 估值一亿的AI核心代码 (20 分)

 

AI.jpg

以上图片来自新浪微博。

本题要求你实现一个稍微更值钱一点的 AI 英文问答程序,规则是:

  • 无论用户说什么,首先把对方说的话在一行中原样打印出来;

  • 消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉;

  • 把原文中所有大写英文字母变成小写,除了 I

  • 把原文中所有独立的 can youcould you 对应地换成 I canI could—— 这里“独立”是指被空格或标点符号分隔开的单词;

  • 把原文中所有独立的 I 和 me 换成 you

  • 把原文中所有的问号 ? 换成惊叹号 !

  • 在一行中输出替换后的句子作为 AI 的回答。

输入格式:

输入首先在第一行给出不超过 10 的正整数 N,随后 N 行,每行给出一句不超过 1000 个字符的、以回车结尾的用户的对话,对话为非空字符串,仅包括字母、数字、空格、可见的半角标点符号。

输出格式:

按题面要求输出,每个 AI 的回答前要加上 AI: 和一个空格。

输入样例:

6
Hello ?
 Good to chat   with you
can   you speak Chinese?
Really?
Could you show me 5
What Is this prime? I,don 't know

输出样例:

Hello ?
AI: hello!
 Good to chat   with you
AI: good to chat with you
can   you speak Chinese?
AI: I can speak chinese!
Really?
AI: really!
Could you show me 5
AI: I could show you 5
What Is this prime? I,don 't know
AI: what Is this prime! you,don't know

 

 

实验代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define MAXN 1001
 5 void solve(string str)
 6 {
 7     vector<string> str_word;
 8     cout<<str<<endl;
 9         cout<<"AI: ";
10         for(int i = 0 ; i < str.length() ; i++)
11         {
12             if(str[i]>='A'&&str[i]<='Z'){if(str[i]!='I')str[i]=str[i]-'A'+'a';}
13              else if((str[i]>='0'&&str[i]<='9')||(str[i]>='a'&&str[i]<='z'))continue;
14             else if(str[i]!=' '){str.insert(i," ");i++;}
15                 if(str[i]=='?'){str[i]='!';}
16         }
17         str_word.clear();
18         string word="";
19         for(int i = 0 ; i < str.size() ; i++)
20         {
21             if(str[i]!=' ')word+=str[i];
22             else if(str[i]==' '){if(word!=""){str_word.push_back(word);word="";}}
23         }
24         if(word!="")
25         {
26             str_word.push_back(word);
27             word="";
28         }
29         int lens_str_word = str_word.size();
30         for(int i=0;i<lens_str_word;i++)
31         {
32             if(str_word[i]=="I"||str_word[i]=="me")str_word[i]="you";
33             else if(str_word[i]=="you")
34             {
35                 if(i<1||str_word[i-1].size()==1)continue;
36                 if(str_word[i-1]=="can"||str_word[i-1]=="could")
37                 {
38                     str_word[i]=str_word[i-1];
39                     str_word[i-1]="I";
40                 }
41             }
42          }
43          
44             for(int i = 0 ; i < lens_str_word ; i++){
45             cout<<str_word[i];
46             if(i==lens_str_word-1)continue;
47                if((str_word[i+1][0]>='a'&&str_word[i+1][0]<='z')||(str_word[i+1][0]>='0'&&str_word[i+1][0]<='9')||(str_word[i+1][0]=='I'))cout<<" ";
48      
49            }
50            cout<<endl;
51         
52     
53     
54 }
55 
56 int main ( int argc , const char * argv[])
57 {
58     int n;
59     cin>>n;
60     getchar();
61     while(n--){
62         string str;
63         getline(cin,str);
64         solve(str);
65         }
66     
67     return 0;
68 }

 

 

设计思路

本体调试过程中遇到的问题及解决方法

一开始don 't  和 prime! 由于都是符号在字母后面的情况且处理方式不同,所以总是出错,但发现可以将符号和字母分开单独处理,输出的时候用条件限制即可输出正确格式。

运行结果截图

 

 

 

第三题

7-3 ***八皇后问题 (20 分)
 

在国际象棋中,皇后是最厉害的棋子,可以横走、直走,还可以斜走。棋手马克斯·贝瑟尔 1848 年提出著名的八皇后问题:即在 8 × 8 的棋盘上摆放八个皇后,使其不能互相攻击 —— 即任意两个皇后都不能处于同一行、同一列或同一条斜线上。

现在我们把棋盘扩展到 n × n 的棋盘上摆放 n 个皇后,请问该怎么摆?请编写程序,输入正整数 n,输出全部摆法(棋盘格子空白处显示句点“.”,皇后处显示字母“Q”,每两格之间空一格)。

输入格式

正整数 n (0 < n ≤ 12)

输出格式

若问题有解,则输出全部摆法(两种摆法之间空一行),否则输出 None。

要求:试探的顺序逐行从左往右的顺序进行,请参看输出样例2。

输入样例1

3 

输出样例1

None

输入样例2

6 

输出样例2

. Q . . . .
. . . Q . .
. . . . . Q
Q . . . . .
. . Q . . .
. . . . Q .

. . Q . . .
. . . . . Q
. Q . . . .
. . . . Q .
Q . . . . .
. . . Q . .

. . . Q . .
Q . . . . .
. . . . Q .
. Q . . . .
. . . . . Q
. . Q . . .

. . . . Q .
. . Q . . .
Q . . . . .
. . . . . Q
. . . Q . .
. Q . . . .

 

 

这道题很神奇,答案是对的,格式一模一样,PTA提交却一直格式错误,就很迷~

 

实验代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define MAXN 12
 4 
 5 int _map[MAXN][MAXN] = {0};
 6 bool flag = false ;
 7 void print(int n)
 8 {
 9         for(int i=1;i<=n;i++){
10         for(int j=1;j<n;j++){
11             if(_map[i][j]==0)
12             cout<<'.'<<' ';
13             else
14             cout<<'Q'<<' ';
15         }
16         if(_map[i][n]==0)
17         cout<<'.'<<endl;
18         else
19         cout<<'Q'<<endl;
20      }
21      cout<<endl;
22 }
23 
24 
25 bool queen_pd(int x , int y ,int n)
26 {
27     for(int i=1;i<=x;i++){
28         if(_map[i][y]){return 0;}
29         else{
30         for(int j=1;j<=n;j++){
31         if(_map[i][j]){if(abs(i-x)==abs(j-y)){return 0;}else{break;}}}
32         }
33         }
34     return 1;
35     
36 }
37 
38 
39 void solve(int n,int num_queen)
40 {
41     if(num_queen>n){print(n);flag = true;}
42     
43     else
44     for(int i = 1 ; i <= n ; i++)
45     {
46 
47         if(queen_pd(num_queen,i,n))
48         {
49             _map[num_queen][i]=1;
50             solve(n,num_queen+1);
51             _map[num_queen][i]=0;
52         }
53 
54     }
55     
56 }
57 
58 int main ( int argc , const char * argv[])
59 {
60     int n;
61     cin>>n;
62     if(n==1)cout<<'Q'<<endl;
63     else if(n==0)cout<<"None";
64     
65     else{
66     solve(n,1);
67         if(!flag) cout<<"None";
68     }
69     return 0;
70 }

 

设计思路

本题调试过程中遇到的问题及解决方法

格式总是错误,答案是对的。。

 

运行结果截图

 

 

 (nmslPTA)

 

 结对编程感想:这次题目只能靠自己理解,合作编辑代码基本靠个人能力..

 

学习总结: 存在的问题 心得 完成作业消耗时间 本周学习内容
第一周 对文件读取数据的运用不是很熟练 多去看关于刷题的书籍,有助于提高自己写题能力,实在不会的可以参考大佬的代码,加以自己理解之后去默写几遍 半个小时左右 文件输入,BFS,DFS,PARTITION算法及简单的贪心算法
第二周 对单纯用数组完成双向链表的操作还是太生疏了,说明对双向链表的运作原理不熟 推荐两本比较好的书《挑战程序设计》《算法竞赛》 半个小时左右 vector数组及list双向链表操作

第三周

指针的概念太久没记有点生疏了 对vector数组使用愈加熟练 一小时左右 数据结构
第四周 对联通二维数组的最大子数和自闭了 多看些算法,不然写题目用什么方法去解决都弄不清 基础题目10分钟,挑战作业现在都在自闭中 迭代器
第五周 最小权值路径最优解该用什么解法 多思考一下如何优化自己的代码,会有新的收获 一个小时 递归和分治法
第六周 指针类型的转换 能用数据结构解决的问题就用数据结构 半小时 windows函数
第七周 指针结构体 对地址的概念要熟悉才能更好的运用指针和结构体 十分钟 依然是windows函数
第八周 数论,递归 多看数论就会变得很牛B 2天

经典数论

 

 

系列一:代码函数  系列二:博客字数

 

posted @ 2019-05-09 23:23  eveilcoo  阅读(785)  评论(0编辑  收藏  举报