详解OJ(Online Judge)中PHP代码的提交方法及要点

来源:互联网 发布:java项目管理 编辑:程序博客网 时间:2024/06/14 13:27
详解OJ(Online Judge)中PHP代码的提交方法及要点
Introduction of How to submit PHP code to Online Judge Systems 
Introduction of How to commit submission in PHP to Online Judge Systems

在目前常用的在线oj中,codeforces、spoj、uva、zoj 等的题目可使用PHP实现基本算法,zoj是目前对PHP支持较好的中文OJ。

PHP是一门比较优秀的语言,但在算法实现上并没像C++那样提供方便的STL(Java、Python也提供了不少system类库可使用),不过PHP中的数组(array)十分强大灵活,用array结合class,实现链表,树,堆,栈等都是没有问题的,挺有挑战性的... 较C++而言,而PHP5.3版本之后提供的标准库SPL(Standard PHP Library)相当于PHP中的"STL",可以直接用 链表,树,堆,栈 等数据结构... ZOJ中的PHP版本是5.4.4的,用SPL应该是可以的...


OJ中针对与PHP的测试用例的输入方式是文件读取,输出是echoprint,注意加上"\n"表示换行... 整体而言,OJ中的PHP输入输出规范和C语言差不多,区别在用:PHP可以不声明变量类型,另外PHP中自定义的抽象数据结构ADT用class实现,而C中用struct.


STDIN是OJ中的PHP环境提供的常量,STDIN等价于fopen("php://stdin","r"));

PHP中的 fscanf($fd, "%d %d %d", $var1, $var2, $varN)==N 用来从文件中按行读取数据。


ZOJ 1001

提交网址:  http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1


A + B Problem


Time Limit: 2 Seconds      Memory Limit: 65536 KB


Calculate a + b

Input

The input will consist of a series of pairs of integers a and b,separated by a space, one pair of integers per line.

Output

For each pair of input integers a and b you should output the sum of a and b in one line,and with one line of output for each line in input.

Sample Input

1 5

Sample Output

6

Hint

Use + operator


试着提交了几次代码,只有下面3种可以AC:

[php] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?php  
  2.     $fd = STDIN; // STDIN是oj提供的常量,等价于 fopen("php://stdin","r"));    
  3.         // $fd=fopen('inputfileName','+r');  
  4.     while(fscanf($fd"%d %d"$a$b)==2)  
  5.         echo ($a + $b)."\n";   
  6. ?>  

将测试的输入放入inputfileName(有无文件扩展名皆可)中,使用注释中的$fd=fopen('inputfileName','+r'); 代替 $fd = STDIN;,即可进行本地测试


[php] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?php  
  2. while(fscanf(STDIN, "%d %d"$a$b) == 2)  
  3.     echo ($a + $b)."\n";   // '\n' 或 PHP_EOL常量均不允许使用  
  4. ?>  

[php] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?php  
  2. while(fscanf(STDIN, "%d %d"$a$b) == 2)  
  3.     print ($a + $b)."\n";  


*推荐使用第一种写法,本地测试方便,上文已提过...


再附上ZOJ 1088相应的已AC代码:

[php] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?php  
  2. function judge($m$n)  
  3. {  
  4.     $from = 0;  
  5.     for($i = 2; $i < $n$i++)  
  6.       $from = ($from + $m)%($i);  
  7.     if($from + 1 == 1) return 1;  
  8.     else return 0;  
  9. }  
  10.     $fd = STDIN;  // STDIN是oj提供的常量,等价于 fopen("php://stdin","r"));  
  11.     while(fscanf($fd"%d"$n)==1 && $n!=0)  
  12.     {  
  13.         $m = 1;  
  14.         while(!judge($m$n))  
  15.         {  
  16.             ++$m;  
  17.         }  
  18.         echo $m."\n";  
  19.     }  


本地测试 代码1(独立文件保存测试输入,fopen):

在php文件的同一目录下创建文件stdin,把测试数据放进去~

[php] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?php  
  2. // To-Do: 约瑟夫环问题  
  3.     $fd = fopen("stdin""r");  
  4.     // $fd = STDIN;  
  5.     function judge($m$n)  
  6.     {  
  7.         $from = 0;  
  8.         for($i = 2; $i < $n$i++)  
  9.           $from = ($from + $m)%($i);  
  10.         if($from + 1 == 1) return 1;  
  11.         else return 0;  
  12.     }  
  13.   
  14.     while(fscanf($fd,"%d"$n)==1 && $n!=0)  
  15.     {  
  16.         $m = 1;  
  17.         while(!judge($m$n))  
  18.         {  
  19.             ++$m;  
  20.         }  
  21.         echo $m."\n";  
  22.     }  

本地测试 代码2(测试数据放在程序代码中, fwrite,fopen,array,支持批量测试)

[php] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?php  
  2. // To-Do: 约瑟夫环问题  
  3. $inFile="./stdin.txt";  
  4. $fd0 = fopen($inFile"w+");      
  5. $data = array(  
  6. "3  
  7. 4  
  8. 5  
  9. 6  
  10. 7  
  11. 8  
  12. 9  
  13. 10  
  14. 11  
  15. 12  
  16. 0"  
  17. );  
  18. fwrite($fd0$data[0]); // 将测试数据放进$data中  
  19. fclose($fd0);  
  20.     $fd = fopen($inFile"r");  
  21.     // $fd = STDIN;  
  22.     function judge($m$n)  
  23.     {  
  24.         $from = 0;  
  25.         for($i = 2; $i < $n$i++)  
  26.           $from = ($from + $m)%($i);  
  27.         if($from + 1 == 1) return 1;  
  28.         else return 0;  
  29.     }  
  30.   
  31.     while(fscanf($fd,"%d"$n)==1 && $n!=0)  
  32.     {  
  33.         $m = 1;  
  34.         while(!judge($m$n))  
  35.         {  
  36.             ++$m;  
  37.         }  
  38.         echo $m."\n";  
  39.     }  



本地测试 代码3(测试数据放在程序代码中, file_put_contents,fopen,array,更简洁,不过file_put_contents( )只能向已经存在的文件中写入数据)

[php] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?php  
  2. // To-Do: 约瑟夫环问题  
  3. $inFile="./stdin.txt";    
  4. $data = array(  
  5. "3  
  6. 4  
  7. 5  
  8. 6  
  9. 7  
  10. 8  
  11. 9  
  12. 10  
  13. 11  
  14. 12  
  15. 0"  
  16. );  
  17.     file_put_contents($inFile$data[0]);  
  18.   
  19.     $fd = fopen($inFile"r");  
  20.     // $fd = STDIN;  
  21.     function judge($m$n)  
  22.     {  
  23.         $from = 0;  
  24.         for($i = 2; $i < $n$i++)  
  25.           $from = ($from + $m)%($i);  
  26.         if($from + 1 == 1) return 1;  
  27.         else return 0;  
  28.     }  
  29.   
  30.     while(fscanf($fd,"%d"$n)==1 && $n!=0)  
  31.     {  
  32.         $m = 1;  
  33.         while(!judge($m$n))  
  34.         {  
  35.             ++$m;  
  36.         }  
  37.         echo $m."\n";  
  38.     }  


几点发现:

1. OJ中PHP的标准输入输出与C的fscanf基本一致;

2. 换行,要求使用"\n",如果用'\n' 或 PHP_EOL常量替代会提示Non-zero Exit Code

3. PHP文件最后的结束符 ?> 可以省略,当然也可写上...

PHP标准库(SPL)中提供的数据结构   PHP version >= 5.3

目录列表

  • SplDoublyLinkedList
  • SplStack
  • SplQueue
  • SplHeap
  • SplMaxHeap
  • SplMinHeap
  • SplPriorityQueue
  • SplFixedArray
  • SplObjectStorage

SPL提供了一组标准数据结构. They are grouped here by their underlying implementation which usually defines their general field of application.

双向链表(DoublyLinkedList)

A Doubly Linked List (DLL) is a list of nodes linked in both directions to each others. Iterator's operations, access to both ends, addition or removal of nodes have a cost of O(1) when the underlying structure is a DLL. It hence provides a decent implementation for stacks and queues.

  • SplDoublyLinkedList
    • SplStack
    • SplQueue

堆(stack)

Heaps are tree-like structures that follow the heap-property: each node is greater than or equal to its children, when compared using the implemented compare method which is global to the heap.

  • SplHeap
    • SplMaxHeap
    • SplMinHeap
  • SplPriorityQueue

数组(array)

Arrays are structures that store the data in a continuous way, accessible via indexes. Don't confuse them with PHP arrays: PHP arrays are in fact implemented as ordered hashtables.

  • SplFixedArray

映射(map)

A map is a datastructure holding key-value pairs. PHP arrays can be seen as maps from integers/strings to values. SPL provides a map from objects to data. This map can also be used as an object set.

  • SplObjectStorage

其他

  • SPL
    • 简介
    • 安装/配置
    • 预定义常量
    • 数据结构
    • 迭代器
    • 接口
    • 异常
    • SPL 函数
    • 文件处理
    • 各种类及接口

下面举一个splheap堆的实例:

[php] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?php  
  2. class MySimpleHeap extends SplHeap  
  3. {  
  4.   //compare()方法用来比较两个元素的大小,决定他们在堆中的位置  
  5.   public function compare( $value1$value2 ) {  
  6.     return ( $value1 - $value2 );  
  7.   }  
  8. }  
  9.    
  10. $obj = new MySimpleHeap();  
  11. $obj->insert( 4 );  
  12. $obj->insert( 8 );  
  13. $obj->insert( 1 );  
  14. $obj->insert( 0 );  
  15.    
  16. echo $obj->top(); //8  
  17. echo $obj->count(); //4  
  18.    
  19. foreach($obj as $number)  
  20.     echo $number."\n";  

此段代码执行结果如下:



相关链接:

http://acm.zju.edu.cn/onlinejudge/faq.do#sample

New SPL Features in PHP 5.3 http://matthewturland.com/2010/05/20/new-spl-features-in-php-5-3/ 

SPL 数据结构 http://php.net/manual/zh/spl.datastructures.php

0 0
原创粉丝点击