POJ 4011 Automated Telephone Exchange 解析

来源:互联网 发布:叶问3游戏网络无连接 编辑:程序博客网 时间:2024/05/17 23:26

http://poj.org/problem?id=4011

Problem A. Automated Telephone Exchange
Input file: ate.in
Output file: ate.out
Time limit: 3 seconds
Memory limit: 256 megabytes
In St Petersburg phone numbers are formatted as “XXX–XX–XX”, where the first three digits represent
index of the Automated Telephone Exchange (ATE). Each ATE has exactly 10 000 unique phone numbers.
Peter has just bought a new flat and now he wants to install a telephone line. He thinks that a phone
number is lucky if the arithmetic expression represented by that phone number is equal to zero. For
example, the phone number 102–40–62 is lucky (102 - 40 - 62 = 0), and the number 157–10–47 is not
lucky (157 -10 - 47 = 100 6= 0).
Peter knows the index of the ATE that serves his house. To get an idea of his chances to get a lucky
number he wants to know how many lucky numbers his ATE has.
Input
The input file contains a single integer number n — the index of Peter’s ATE (100 <= n <=  999).
Output
Output a single integer number — the number of lucky phone numbers Peter’s ATE has.
Examples
ate.in ate.out
196        3
239        0

这是一道求解线性不定方程组的题目。我的思路如下:

         x + y =n

        0 <= x <= 99

        0 <= y <= 99   => 0<=n-x<=99 =>  n-99 <= x <=n

        因此,  本题答案 = 区间 [ n-99, 99] 的长度 ,显然 n-99<=99 ,即 n <=198 ,该方程组才有解。分析到这里,下面的代码就很容易写出来了:

#include"stdio.h"int main(){FILE *fp1=fopen("ate.in","r");FILE *fp2=fopen("ate.out","w");int n;while(!feof(fp1)){fscanf(fp1,"%d",&n);if(n>=199)fprintf(fp2,"0\n");elsefprintf(fp2,"%d\n",199-n);}fclose(fp1);fclose(fp2);return 0;}

         

          但是,提交以后是WA,看了discuss才知道此题还是控制台输入输出,压根就不是文件输入输出,题目误导人啊~,将输入输出稍作修改得到:

#include"stdio.h"int main(){int n;while(scanf("%d",&n)!=EOF){if(n>=199)printf("0\n");elseprintf("%d\n",199-n);}return 0;}
          7511739694yinjili164K16MSC++160B2013-07-06 19:58:59

           耗时16MS,在C++中排名第75。

           因为我看到有人耗时为0MS,所以我尝试改进代码。首先,我想到打表,代码如下:

#include"stdio.h"int main(){int a[1000]={0};int i;a[198]=1;for(i=197;i>=100;i--)a[i]=a[i+1]+1;int n;while(scanf("%d",&n)!=EOF){printf("%d\n",a[n]);}return 0;}

yinjili4011Accepted164K63MSC++202B

          耗时63MS。

          我发现n>=199和199-n操作有点相似,考虑将其合为一个操作,并将199用16进制表示,因为整数在计算机中以二进制形式存储,二进制和16进制转换要快一点。

          改进后的代码如下:

#include"stdio.h"int main(){int n,t;while(scanf("%d",&n)!=EOF){t=0xC7-n;printf("%d\n",t>0? t:0);}return 0;}

yinjili4011Accepted164K0MSC++136B711740030(3)yinjili164K0MSC++136B2013-07-06 21:47:04

   耗时0MS,在C++中排名第7。

   

          尝试改善代码,提高性能,不仅仅满足AC !