九度OJ——1384
来源:互联网 发布:留学低龄化数据 编辑:程序博客网 时间:2024/04/30 11:23
最近在看《C++大学教程》和《剑指offer》,但仅仅是看代码,没有实际coding。鉴于coding是要动手实践的,因此开始要练习了。所以就从九度OJ上的“剑指offer”部分开始练习。第一题1348,找出二维数组中的数。代码其实很简单,但是前前后后折腾了一整天。下面就自己解析一下代码吧,其实核心就是书上的。但还是来总结一下吧,后面做的每道题争取都能总结一下。
最后AC的代码如下:
#include<iostream>#include <cstdio>#include <cstdlib>using namespace std;#define MAX 1002001bool find(int *matrix, int rows, int cols, int t){bool found = false;int row = 0;int col = cols - 1;if(matrix != NULL && rows > 0 && cols > 0){while(row < rows && col >= 0){if(matrix[row * cols + col] == t){found = true;break;}else if(matrix[row * cols + col] > t)col--;else row ++;}}return found;}int main(){int rows;int cols;int t;bool found = false;static int array[MAX] = {0};//int array[MAX] = {0}; //while(cin >> rows)while(scanf("%d", &rows) != EOF){//cin >> cols >> t;scanf("%d%d", &cols, &t);for(int i=0; i<rows; i++) //初始化数组for(int j=0; j<cols; j++)//cin >> array[i * cols + j];scanf("%d", &array[i * cols + j]); found = find(array, rows, cols, t);if(found == true)//cout << "Yes\n";printf("Yes\n");else //cout << "No\n";printf("No\n");}return 0;}
其实很多时间都是花在输入输出上,因为主要部分就是书上的代码,也没有创新。因为想以后就用C++,所以想保持一下代码的C++风格,即输入输出用cin和cout。但是这样会超时。最后在大钊的点拨下,将此改为scanf和printf后,解决了“超时”的问题。这样,提交之后还是错误的原因却是我没有注意到“Yes/No”的大小写问题,囧!第一次做OJ,完全没有经验。
其实C++是不提倡使用scanf和printf的,主要原因是C++提供了流运算符>>/<<,而且能输出对象,scanf和printf是不能的。当然还有其它原因:
(引自C++为什么不提倡使用scanf和printf函数)
int printf( char *, ...);和int scanf( char *, ...);
我们看到,除了第一个参数要求是char *以外,其余参数的类型不限,个数也不限。从这一点能够看出,C语言对函数参数的数据类型是不做严格的检查的,但是C++语言却是要做严格的类型检查的,这与C++支持函数重载有关。
再者,在一个程序里,如果cin、cout和scanf、printf混合使用,系统不能保证他们的执行次序是正确的,假如我们希望输出‘我吃’,也许输出的是‘吃我’。尽管C++提供了解决这个问题的途径,但是一般不提倡这样做。
那怎么写代码能做到测试用例的无限次输入和判断文件结尾(EOF)呢?C++中是这样:while(cin >> variable),非常简洁!当输入一个int型数时,由cin传到intvariable,循环条件成立,于是转到循环体中执行。之后若循环体执行完,再来判断条件是否成立,若此时遇到文件结尾,则由于不是int型,而发生错误,于是条件不成立,即退出循环。
而用scanf时,则是while(scanf("%d", &rows) != EOF),即要将scanf的返回值与EOF比较,其实EOF就是-1。我们可能会感到奇怪,为什么scanf会有返回值,平时调用scanf和printf时,不是直接调用的吗?其实它们都是返回int型变量的函数,如上面所引用的。
int a, b;int num, n;num = scanf("%d%d",&a, &b);n = printf("=========\n");printf("%d\n%d", num, n);
如上述代码运行后,输出为:
=========
2
10
即scanf返回的是成功读入变量的个数,而printf则返回的是它打印出的字符数。因此在while循环条件中,先输入一个变量,scanf返回1,与EOF(-1)不等,于是,进入循环体。最后当遇到EOF时,返回-1。于是就退出循环。
九度OJ可能对C++的支持不好,所以我们要写出如此风格不一致的代码,实在是难受!
再有就是可以先定义出一个最大容量的数组,然后再去初始化,但这就会占据更多的内存。如果用new/delete的话,则是用时间来换空间。需要说明的是,用static声明的数组是存储在堆中,否则是存在栈中。在本题中,如果不用static来声明的话,在VS2012中会出现stack flow的错误。但是提交到OJ上去,是能AC的!只不过有3个测试用例的时间都会比加static的时间要长。
不加static:
加了static:
我在九度OJ的论坛上,还看到了很多暴力解法,我觉得这是很好的,因为他们观察题目很仔细,也很灵活。我可能是因为直接就根据书上所说的,也没有过多地去考虑,所以就生搬硬套了!因为此题是有缺陷的,所以可以直接边输入数组的值,边进行判断,是可以达到解题的目的的。当然书上要考察的点不是这样。
最后,总结一下:
1.第一次做OJ,主要是在输入输出的问题花费了较多时间,不过也弄懂了怎么分别用cin/scanf来表示文件结束,也掌握了九度OJ的解题流程。后面加油了!
2.输出一定要和题目所要求的一致。
- 九度OJ——1384
- 九度OJ —— 1000
- 九度OJ —— 1001
- 九度OJ —— 1002
- 九度OJ —— 1003
- 九度OJ —— 1004
- 九度OJ —— 1005
- 九度OJ——1014排名
- 九度OJ——1172哈夫曼树
- 九度OJ——1201二叉排序树
- 九度OJ——1144Freckles
- 九度OJ—题目1032:ZOJ
- 九度OJ—题目1057:众数
- 九度OJ—题目1056:最大公约数
- 【九度OJ】:九度OJ 1050
- 【九度OJ】:九度OJ 1053
- 【九度OJ】:九度OJ 1056
- 【九度OJ】:九度OJ 1059
- 优先队列版子
- 【liunx命令学习】nc扫描远程端口
- 算法竞赛入门经典-第三章源代码
- 【Leetcode长征系列】Remove Duplicates from Sorted List II
- uva674 - Coin Change(完全背包)
- 九度OJ——1384
- [学习小结]Ajax基本操作_XML格式&&在jQuery中如何操作
- Linux网络编程(七) 套接字选项
- 【hiho一下】第五周 数字三角形
- Win32应用程序窗口无法弹出
- 数据库视频总结
- 牛顿迭代法求开方值
- smartweather API 使用java 生成key的方法
- Android:Cursor