poj 1002

来源:互联网 发布:java 泛型编程 编辑:程序博客网 时间:2024/05/16 17:56

 研究了半天,结果果然是超时了。其实数据处理的时间应该不长,关键是读入数据的时间太长了。还是记下来留作念想吧。

#include "poj.h"#include <iostream>#include <string>#include <vector>#include <algorithm>using namespace std;char Codes[31] = {'0','0','A','D','G','J','M','P','T','W',  '0','0','B','E','H','K','N','R','U','X',  '0','0','C','F','I','L','O','S','V','Y'};class Word{public:string w;int count;bool operator ==(const Word &value)    {return value.w == this->w;    }bool operator>(const Word& value){return this->w > value.w;}bool operator<(const Word& value){return this->w < value.w;}};string translate(string original){string result = "";for(int i = 0; i < original.length();i++){char c = original[i];if(c == '-')continue;if(c >= '0' && c<= '9'){result += c;}else{//find the number c representsfor(int j = 0; j < 30;j++){if(c == Codes[j]){result += j%10 + '0';break;}}}}return result;}void p1002(){int i,n;cin>>n;vector<string> data;vector<Word> dumpnumber;for(i = 0; i < n; i++){string a;cin>>a;string t = translate(a);if( find(data.begin(), data.end(), t) != data.end()){Word word;word.w = t;vector<Word>::iterator it = find(dumpnumber.begin(), dumpnumber.end(),word);if(it != dumpnumber.end()){it->count++;}else{word.count=2;dumpnumber.push_back(word);}}data.push_back(t);}sort(dumpnumber.begin(),dumpnumber.end());vector<Word>::iterator it = dumpnumber.begin();if(dumpnumber.empty()){cout<<"No duplicates."<<endl;}while(it != dumpnumber.end()){for(i = 0; i < 3; i ++)cout<<it->w[i];cout<<"-";for(;i<7;i++)cout<<it->w[i];cout<<" "<<it->count<<endl;it++;}}

终于决定用暴力方法,写了个丑陋的办法,果然AC了,用时1200MS:

#include <iostream>#include <string>#include <sstream>//#include "poj.h"#using <System.dll>using namespace System;using namespace System::Diagnostics;using namespace std;char Codes[31] = {'0','0','A','D','G','J','M','P','T','W',  '0','0','B','E','H','K','N','R','U','X',  '0','0','C','F','I','L','O','S','V','Y'};int translate(string original){int result = 0, index = 1000000;for(int i = 0; i < original.length();i++){char c = original[i];if(c == '-')continue;if(c >= '0' && c<= '9'){result += index * (c - '0');index /= 10;}else{//find the number c representsfor(int j = 0; j < 30;j++){if(c == Codes[j]){result += index * (j%10);index /= 10;break;}}}}return result;}int count[10000000] = {0};int main(){int i,t,n,flag = -1;string a;stringstream ss;cin>>n;Stopwatch ^ stopWatch;stopWatch = Stopwatch::StartNew();for(i = 0; i < n; i++){cin >> a;t = translate(a);count[t]++;}for(i = 0; i < 10000000; i++){int c = count[i];if(c<2)continue;if(flag<0)flag = 1;ss.clear();ss<<i;ss>>a;while(a.length() < 7) a = '0' + a;cout<<a[0]<<a[1]<<a[2]<<"-"<<a[3]<<a[4]<<a[5]<<a[6]<<" "<<c<<endl;}if(flag<0)cout<<"No duplicates."<<endl;stopWatch->Stop();Int64 ticksThisTime = stopWatch->ElapsedMilliseconds;cout<<"time:"<<ticksThisTime<<endl;system("PAUSE");return 0;}

同时学学别人家的代码:

先排序再找重复?还是找出重复再排序?这是个问题。

我试着换成这种输入方式,但并没有让我的代码更快,反而TLE了。不过多重IF的语句确实比for循环去char数组里找快一些貌似。

但是C语言天然优势使得这段代码只用了800MS左右。

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <ctype.h>char pn[100000][8];void main (){  int i, j, n, c;  int none = 1;  scanf ("%d", &n);  for (i = 0; i < n; i++)    {      j = 0;      while (j < 7){  if (!isalnum (c = getchar ())) continue;  if (c == 'A' || c == 'B' || c == 'C') c = '2';  if (c == 'D' || c == 'E' || c == 'F') c = '3';  if (c == 'G' || c == 'H' || c == 'I') c = '4';  if (c == 'J' || c == 'K' || c == 'L') c = '5';  if (c == 'M' || c == 'N' || c == 'O') c = '6';  if (c == 'P' || c == 'R' || c == 'S') c = '7';  if (c == 'T' || c == 'U' || c == 'V') c = '8';  if (c == 'W' || c == 'X' || c == 'Y') c = '9';  pn[i][j++] = c;}      pn[i][7] = '\0';    }  qsort (pn, n, 8, (int (*) (const void *, const void *)) strcmp);  j = 0;  for (i = 1; i < n; i++)  {    if (strcmp (pn[i], pn[j]) != 0)      {if (i - j > 1)  {printf (  "%c%c%c-%s %d\n", pn[j][0], pn[j][1], pn[j][2], pn[j] + 3, i - j);none = 0;  }j = i;      }  }  if (i - j > 1)    {      printf ("%c%c%c-%s %d\n", pn[j][0], pn[j][1], pn[j][2], pn[j] + 3, i - j      );      none = 0;    }  if (none)    printf ("No duplicates.\n");  system("PAUSE");}

这是另一段代码,思路也是先排序,然后一边找重复一边输出:(转自http://blog.chinaunix.net/uid-8059407-id-2034320.html)

#include <stdio.h>#include <stdlib.h>#include <string.h>char map[26] = {'2', '2', '2', '3', '3', '3', '4', '4', '4',                 '5', '5', '5', '6', '6', '6', '7', '7', '7',                 '7', '8', '8', '8', '9', '9', '9', '9'};//按键映射表char phone[100000][9];    //全部电话号码int n;                    //电话号码的数量char number[80];        //一个未经处理的电话号码int main(void){    int loop;                    //循环变量    int phone_i=0, phone_j=0;    //phone数组的下标    int tag = 0;                //重复标志,0没有处于一个重复,1有重复    int count = 1;                //重复次数    scanf("%d", &n);    for(phone_i=0; phone_i<n; phone_i++){//格式化所有输入数据为111-1111的形式        scanf("%s", number);        for(loop=0; number[loop]!='\0'; loop++){//检查每一个字符            if(phone_j == 3){//第四个字符必须是'-'                phone[phone_i][phone_j] = '-';                phone_j++;            }            if(number[loop]>='0' && number[loop]<='9'){//当前字符是数字                phone[phone_i][phone_j] = number[loop];            }            else if(number[loop]>='A' && number[loop]<='Z'){//当前字符是大写字母                phone[phone_i][phone_j] = map[number[loop]-'A'];            }            else if(number[loop] == '-'){//忽略'-'                continue;            }            phone_j++;        }        phone_j = 0;    }        //排序全部电话号码    qsort(phone, n, 9, strcmp);    for(loop=1; loop<n; loop++){//检查重复次数,输出结果        if(strcmp(phone[loop], phone[loop-1]) == 0){            tag = 1;            count++;        }        else{//没有重复            if(count > 1){                printf("%s %d\n", phone[loop-1], count);            }            count = 1;        }    }    if(count > 1){//查看最后一条记录是否有重复        printf("%s %d\n", phone[loop-1], count);    }    if(!tag)         printf("No duplicates.\n");    return 0;}

这个很有借鉴意义,根据输入来确定自定义数据指针的长度:(转自http://blog.csdn.net/hello_cosmos/article/details/8683599)

#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct __data{   int telNum;   int repTim;} da;int main(){da *data;int numOfRecord,i;char temp[2000];  //数组开小了会WA。。。我了个擦。。。多么变态的测试数据啊。。第二第三次WA都是这个问题scanf("%d",&numOfRecord);data=(da *)calloc(numOfRecord,sizeof(da));for (i=0;i<numOfRecord;i++){scanf("%s",temp);stdlizeNum(temp,&(data[i]));}sortPrintf(data,numOfRecord);  free(data);  return 0;}int stdlizeNum(char *num,da *ans){  int len=strlen(num);  int i;  int k=0;    ans->repTim=0;  ans->telNum=0;  for (i=0;i<len;i++){     switch(num[i]){     case 'A':     case 'B':     case 'C':      ans->telNum+=2;      ans->telNum*=10;     break;     case 'D':     case 'E':     case 'F':      ans->telNum+=3;      ans->telNum*=10;     break;     case 'G':     case 'H':     case 'I':      ans->telNum+=4;      ans->telNum*=10;     break;     case 'J':     case 'K':     case 'L':      ans->telNum+=5;      ans->telNum*=10;     break;     case 'M':     case 'N':     case 'O':      ans->telNum+=6;      ans->telNum*=10;     break;     case 'P':     case 'R':     case 'S':      ans->telNum+=7;      ans->telNum*=10;     break;     case 'T':     case 'U':     case 'V':      ans->telNum+=8;      ans->telNum*=10;     break;     case 'W':     case 'X':     case 'Y':      ans->telNum+=9;      ans->telNum*=10;     break;     case '-':     break;     default:      ans->telNum+=(int)(num[i]-'0');      ans->telNum*=10;     break;     }  }  ans->telNum/=10;}int sortCmp_fun(const void *a,const void *b){      return ((*(da *)a).telNum)-((*(da *)b).telNum);}int sortPrintf(da *input,int len){int i,offOn;qsort(input,len,sizeof(da),sortCmp_fun);    for (i=0;i<len;i++){     if (input[i].telNum==input[i-1].telNum){        input[i].repTim=input[i-1].repTim+1;        input[i-1].repTim=0;     }  }  offOn=0;  for (i=0;i<len;i++){     if (input[i].repTim!=0){       offOn=1;        printf("%03d-%04d %d\n",input[i].telNum/10000,input[i].telNum%10000,input[i].repTim+1);  //"%d"这里不会出'0',而"%0d"会打印出来,第一次WA就是这里出错了     }  }  if (offOn==0){  printf("No duplicates.\n");  }}


这里也有一些调试和借鉴的地方:(转自http://blog.csdn.net/wmmthu/article/details/7505850)

#include <stdio.h>#include <string.h>#include <stdlib.h>#define UNCODE(a) (a>='A'?((a>'Q'?(a-'A'-1):(a-'A'))/3+2):a-'0')//#define DEBUGint uncode(char* s){int i;int result=0;for(i=0;i<strlen(s);i++){if(s[i]=='-') continue;result=result*10+UNCODE(s[i]);}return result;}int cmp(const void* a,const void* b){return *(int*)a-*(int*)b;}int main(){#ifdef DEBUGfreopen("data.dat","r",stdin);//freopen("out.dat","w",stdout);#endifint* store;char s[50];int time;int n=0;int i;int start,value;int dup=0;scanf("%d",&time);store=(int*)malloc(sizeof(int)*(time));for(n=0;n<time;n++){scanf("%s",s);store[n]=uncode(s);} qsort(store,time,sizeof(store[0]),cmp);value=store[0];start=0;for(n=0;n<time;n++){if(store[n]!=value){ if((n-start)>1){printf("%03d-%04d %d\n",store[start]/10000,store[start]%10000,n-start);dup=1;}start=n;value=store[n];}}if((n-start)>1){printf("%03d-%04d %d\n",store[start]/10000,store[start]%10000,n-start);dup=1;}if(!dup){printf("No duplicates.\n");}free(store);return 1;}

/* Copyright Derek Kisman (ACM ICPC ECNA 1999) */char map[26] = {'2', '2', '2', '3', '3', '3', '4', '4', '4','5', '5', '5', '6', '6', '6', '7', 0, '7', '7', '8', '8', '8', '9', '9', '9', 0};char ph[100000][9];int nph;char buf[1000];main() {int i, j, k, x, y, z, n;char ch;memset( ph, 0, sizeof(ph) );scanf( " %d", &nph );for( i = 0; i < nph; i++ ) {scanf( " %s", buf );x = 0;for( j = 0; buf[j]; j++ ) {if( buf[j] == '-' ) continue;if( buf[j] >= 'A' && buf[j] <= 'Z' ) buf[j] = map[buf[j]-'A'];ph[i][x++] = buf[j];if( x == 3 ) ph[i][x++] = '-';}}qsort( ph, nph, 9, strcmp );x = 1; z = 0;for( i = 1; i < nph; i++ ) {if( strcmp( ph[i-1], ph[i] ) ) {if( x > 1 ) {printf( "%s %d\n", ph[i-1], x );z = 1;}x = 1;} else {x++;}}if( x > 1 ) {printf( "%s %d\n", ph[i-1], x );z = 1;}if( !z ) printf( "No duplicates.\n" );}


0 0
原创粉丝点击