Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
写了12K的代码,1A了,高兴。In Reply To:Re:test data Posted by:yygy at 2023-05-13 13:00:27 > // MyFirstApp.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 > // > > #include <iostream> > #include <vector> > #include <stdio.h> > #include <math.h> > #include <algorithm> > > using namespace std; > > typedef __int64 lld; > > const int MAXN = 20010; > > struct BigNum > { > int dig[512];//题目说最多200位,平方之后最多400位 > int len; > BigNum() {} > BigNum(int arr[], int size) > { > clr(); > len = size; > for (int i = 0; i < len; i++) > { > dig[len - i - 1] = arr[i]; > } > } > void clr() > { > memset(dig, 0, sizeof(int) * 512); > len = 1; > } > > void operator --() > { > dig[0]--; > int bit=0; > while (dig[bit] < 0) > { > dig[bit] += 10; > dig[bit + 1] --; > bit++; > } > > while (len > 1 && dig[len - 1] == 0) > { > len--; > } > } > > int Compare(const BigNum& other) const > { > if (len < other.len) > { > return -1; > } > > if (len>other.len) > { > return 1; > } > > for (int i = len-1; i>=0; i--) > { > if (dig[i] != other.dig[i]) > { > return dig[i] - other.dig[i]; > } > } > > return 0; > } > > void operator ++() > { > dig[0]++; > int bit = 0; > while (dig[bit] > 9) > { > dig[bit] -= 10; > dig[bit + 1] ++; > bit++; > } > > if (dig[len]) > { > len++; > } > } > > void Add(int x) > { > dig[0]+=x; > for(int i=0;i<len;i++) > { > if(dig[i]>=10) > { > dig[i+1]+=dig[i]/10; > dig[i]%=10; > } > } > > while(dig[len]) > { > dig[len+1]+=dig[len]/10; > dig[len]%=10; > len++; > } > } > > void print() > { > for(int i=len-1;i>=0;i--) > { > printf("%d", dig[i]); > } > } > }; > > bool IsSuffix(const BigNum& num, int* pat, int size) > { > if (size > num.len) > { > return false; > } > > for (int i = 0; i < size; i++) > { > if (num.dig[i] != pat[size - i - 1]) > { > return false; > } > } > > return true; > } > > bool Match(int* pat, int patlen, const BigNum& tmp, int last) > { > int i = 0; > for (i = 0; i < tmp.len && last + i < patlen; i++) > { > //BigNum从高位比起 > if (tmp.dig[tmp.len-i-1] != pat[last + i]) > { > return false; > } > } > > return i == tmp.len || last + i == patlen; > } > > void MakeStr(int *pat, int len, std::vector<int>& a) > { > for(int i=0;i<len;i++) > { > a.push_back(pat[i]); > } > } > > bool Match(std::vector<int>::iterator beginA, std::vector<int>::iterator endA, > const std::vector<int>& strA) > { > int i=0; > while(beginA<endA) > { > if(*beginA!=strA[i]) > { > return false; > } > i++; > beginA++; > } > > return true; > } > > void Concat(const std::vector<int>& strb, const std::vector<int>& stra, > int pos, > std::vector<int>& num) > { > int rearSize=stra.size()-(strb.size()-pos); > num=strb; > num.reserve(rearSize+strb.size()); > > for(int i=stra.size()-rearSize;i<stra.size();i++) > { > num.push_back(stra[i]); > } > } > > void FindSeperateTwoSegments(int patlen, int* pat, BigNum& ans, int& offset) > { > //枚举中间断开位置 > for(int i=0;i+1<patlen;i++) > { > std::vector<int> stra, strb; > //两个串保存起来 > MakeStr(pat, i+1, stra); > MakeStr(pat+i+1, patlen-i-1, strb); > > //寻找一个前面的前缀等于后面的后缀的位置,然后把这两个串叠起来 > //枚举后面串对齐第一个串的首位置 > for(int pos=0;pos<=strb.size();pos++) > { > if(strb.size()-pos>stra.size()) > { > //后面的串太短,覆盖不了前面串的后缀 > continue; > } > > if(Match(strb.begin()+pos, strb.end(), stra)) > { > std::vector<int> num; > Concat(strb, stra, pos, num); > BigNum pre=BigNum(num.data(), num.size()); > if (IsSuffix(pre, pat, i + 1)) > { > BigNum tmp = pre; > ++tmp; > int last=i+1; > > if (Match(pat, patlen, tmp, last)) > { > int newOffset = 1 + pre.len - (i + 1); > int diff=pre.Compare(ans); > if(diff<0) > { > ans=pre; > offset=newOffset; > } > else if(diff==0 && newOffset<offset) > { > offset=newOffset; > } > } > > } > } > } > } > } > > void FindSeperateSeveralSegments(int patlen, int* pat, BigNum& ans, int& offset) > { > //把pat分解成前后两部分,后面一部分是由n,n+1,n+2...堆起来的,那么后面的开头数字长度不能小于第一部分 > for (int i = 0; patlen - (i + 1) >= i + 1; i++) > { > if (pat[i + 1] == 0) > { > //首位数字必须非0 > continue; > } > //枚举后面数字[i+1,j]区间为第一个数字 > //j-i>=i+1 > for (int j = i + i + 1; j < patlen; j++) > { > printf("i=%d j=%d\n",i,j); > BigNum head = BigNum(pat + i + 1, j - i); > BigNum pre = head; > --pre; > printf("pre="); pre.print(); > cout<<endl; > > //判断前面部分是否为head-1的后缀 > if (!IsSuffix(pre, pat, i + 1)) > { > continue; > } > > printf("suffix success\n"); > > int last = i+1; > BigNum tmp = head; > //tmp一直++,把last后面的数字依依匹配,看看能不能配完 > while (last < patlen) > { > if (!Match(pat, patlen, tmp, last)) > { > break; > } > > last += tmp.len; > ++tmp; > } > > printf("last=%d patlen=%d\n", last, patlen); > > if (last >= patlen)//匹配成功 > { > > int newOffset = 1 + pre.len - (i + 1); > int diff=pre.Compare(ans); > > printf("one solution = "); > pre.print(); > > printf(", offset=%d\n", newOffset); > //记录一下现在的答案 > if (diff<0) > { > ans = pre; > offset = newOffset; > } > else if(diff==0 && newOffset<offset) > { > offset=newOffset; > } > } > } > } > } > > BigNum Add(const BigNum& a, const BigNum& b) > { > BigNum c; > c.clr(); > c.len=std::max(a.len, b.len); > > for(int i=0;i<c.len;i++) > { > c.dig[i]=a.dig[i]+b.dig[i]; > } > > for(int i=0;i<c.len;i++) > { > if(c.dig[i]>=10) > { > c.dig[i+1]+=c.dig[i]/10; > c.dig[i]%=10; > } > } > > if(c.dig[c.len]) > { > c.len++; > } > > return c; > } > > void MulTen(BigNum& num) > { > for(int i=num.len;i>0;i--) > { > num.dig[i]=num.dig[i-1]; > } > num.dig[0]=0; > num.len++; > } > > int BitCount(int n) > { > if(n==0) > { > return 1; > } > > int len=0; > while(n) > { > len++; > n/=10; > } > > return len; > } > > BigNum Mul(const BigNum& a, int b) > { > BigNum c; > c.clr(); > if(b==0) > { > return c; > } > c.len=a.len+BitCount(b); > for(int i=0;i<a.len;i++) > { > c.dig[i]=a.dig[i]*b; > } > > for(int i=0;i<c.len;i++) > { > if(c.dig[i]>=10) > { > c.dig[i+1]+=c.dig[i]/10; > c.dig[i]%=10; > } > } > > while(c.len>1&& c.dig[c.len-1]==0) > { > c.len--; > } > > return c; > } > > BigNum Minus(const BigNum& a,const BigNum& b) > { > BigNum c; > c.clr(); > c.len=a.len; > for(int i=0;i<a.len;i++) > { > c.dig[i]=a.dig[i]-b.dig[i]; > } > > for(int i=0;i<a.len;i++) > { > if(c.dig[i]<0) > { > c.dig[i]+=10; > c.dig[i+1]--; > } > } > > while(c.len>1&&c.dig[c.len-1]==0) > { > c.len--; > } > > return c; > } > > void CalcIndex(const BigNum& num, int offset, BigNum& pos) > { > pos.clr(); > BigNum nine; > BigNum one; > nine.clr(); > nine.dig[0]=9; > one.clr(); > one.dig[0]=1; > //先计算长度比num短的数字长度总和 > for(int bitLen=1;bitLen<num.len;bitLen++) > { > //长度为bitLen的有nine个,每个长度为bitLen > BigNum length=Mul(nine,bitLen); > printf("bitLen=%d\n", bitLen); > printf("nine="); > nine.print(); > std::cout<<endl; > printf("length="); > length.print(); > std::cout<<endl; > pos=Add(pos, length); > printf("tempPos="); > pos.print(); > std::cout<<endl; > MulTen(nine); > MulTen(one); > } > > printf("small length = "); > pos.print(); > std::cout<<std::endl; > > //统计长度为num.len的个数,以及长度 > BigNum equalLengthNum=Minus(num, one); > > BigNum otherLength=Mul(equalLengthNum, num.len); > pos=Add(pos, otherLength); > > pos.Add(offset); > } > > int main() > { > char str[512]; > int pat[512]; > int patlen = 0; > while (cin.getline(str, 1024)) > { > patlen = strlen(str); > for (int i = 0; i < patlen; i++) > { > pat[i] = str[i] - '0'; > } > > //一个初始解,也就是仅由于段组成的 > BigNum ans = BigNum(pat, patlen); > int offset = 1; > > if (ans.dig[ans.len - 1] == 0) > { > //最高位为0,需要添加一位,比如0,是10后面来的,01应该是101后面来的 > offset++; > ans.dig[ans.len] = 1; > ans.len++; > } > > //假设由若干个数字拼成,寻找答案 > FindSeperateSeveralSegments(patlen, pat, ans, offset); > > //假设只由两个数字拼成,寻找答案 > FindSeperateTwoSegments(patlen, pat, ans, offset); > > printf("ans="); > ans.print(); > std::cout<<std::endl; > printf("offset=%d\n", offset); > > BigNum pos; > CalcIndex(ans, offset, pos); > > pos.print(); > cout<<endl; > } > return 0; > } > > /* > http://poj.org/problem?id=1863 > Subnumber > 要考虑前导0,一堆0的情况 > > 1 > ans=1 > offset=1 > 2 > ans=2 > offset=1 > 3 > ans=3 > offset=1 > 101 > ans=10 > offset=1 > 1234 > ans=1 > offset=1 > 234 > ans=2 > offset=1 > 11 > ans=11 > offset=1 > 12 > ans=1 > offset=1 > 13 > ans=13 > offset=1 > 41 > ans=41 > offset=1 > 10111 > ans=110 > offset=2 > 011 > ans=10 > offset=2 > 121 > ans=121 > offset=1 > 123412351236123712381239 > > 121314 > > 1234123 > > 23412 > 3412 > > */ Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator