Topcoder SRM 583 DIV2 解题报告
-----------------
250 SwappingDigits
给一个数字串,要求交换两个数字的位置得到一个尽可能小的数字。(可以不交换)
----
从高位向低位枚举,对每一位,从低位向高位找一个比它小的数,若能找到则交换即答案。
对首位不能为0进行特殊处理。
#include <iostream> #include <string> #include <algorithm> using namespace std; class SwappingDigits{ private: public: string minNumber(string num) { int n=num.length(); int p; for (int i=0;i<n;i++) { p=i; for (int j=n-1;j>i;j--) if (num[j]<num[p]&&(i!=0||num[j]!='0')) p=j; if (p!=i){ swap(num[i],num[p]); break; } } return num; } };-----------------
550 IDNumberVerification
判断一个18位的身份证号是否合法,并输出性别。
----
直接模拟即可。注意sequential code不能为000。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <vector> using namespace std; const int day12[13]={ 0,31,28,31,30,31,30,31,31,30,31,30,31 }; const int lday12[13]={ 0,31,29,31,30,31,30,31,31,30,31,30,31 }; class IDNumberVerification{ private: int tonum(string s){ int ret=0; int len=s.length(); for (int i=0;i<len;i++) ret=ret*10+s[i]-'0'; return ret; } int cmpday(int y1,int m1,int d1,int y2,int m2,int d2){ if (y1==y1&&m1==m2&&d1==d2) return 0; if (y1>y2) return 1; if (y1==y2&&m1>m2) return 1; if (y1==y2&&m1==m2&&d1>d2) return 1; return -1; } bool isleap(int year){ if ( (year%4==0&&year%100!=0)||(year%400==0) ) return true; return false; } bool isdate(int y,int m,int d){ if (y<1900||y>2011) return false; if (m>12||m<1) return false; if (d<1) return false; if (!isleap(y)){ if (d>day12[m]) return false; } else if (d>lday12[m]) return false; return true; } bool getx(string id){ long long a=0; long long bit=1; for (int i=17;i>=0;i--){ if (id[i]=='X') a+=10*bit; else a+=(id[i]-'0')*bit; bit*=2; } if (a%11==1) return true; return false; } public: string verify(string id, vector<string> regionCodes) { bool find; string male="Male"; string female="Female"; string invalid="Invalid"; string region=id.substr(0,6); string birthday=id.substr(6,8); string sequential=id.substr(14,3); string checksum=id.substr(17,1); int year=tonum(birthday.substr(0,4)); int month=tonum(birthday.substr(4,2)); int day=tonum(birthday.substr(6,2)); find=false; int siz=regionCodes.size(); for (int i=0;i<siz;i++) if (regionCodes[i]==region){ find=true; break; } if (!find) return invalid; if (!isdate(year,month,day)) return invalid; if (cmpday(year,month,day,1900,1,1)<0|| cmpday(year,month,day,2011,12,31)>0) return invalid; if (!getx(id)) return invalid; if (sequential=="000") return invalid; if (tonum(sequential)&1) return male; else return female; } };-----------------
900 GameOnABoard
有一个由0和1组成的n*m的棋盘,A从中选一个点,B从中选一个点,两点间最短数字和为L。
A要使L最小,B要使L最大。双方都足够聪明。
----
直接n*m次最短路居然木有超时。。。这不科学。。。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <vector> #include <cmath> #include <queue> using namespace std; const int INF=1e9+7; const int maxm=111111; const int maxn=11111; const int direct[4][2]={ {0,1},{1,0},{-1,0},{0,-1} }; struct EDGENODE{ int to; int next; int w; }; class CSPFA{ private: EDGENODE edges[maxm]; int head[maxn],edge,node; bool visit[maxn]; int outque[maxn]; queue<int>que; public: int dist[maxn]; void addedge(int u,int v,int c){ edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++; //edges[edge].w=c,edges[edge].to=u,edges[edge].next=head[v],head[v]=edge++; } void init(int n){ memset(head,-1,sizeof(head)); edge=0; node=n; } bool SPFA(int src) { int top; for (int i=0;i<=node;i++) dist[i]=INF; memset(visit,0,sizeof(visit)); memset(outque,0,sizeof(outque)); while (!que.empty()) que.pop(); que.push(src); visit[src]=true; dist[src]=0; while (!que.empty()){ top=que.front(); que.pop(); visit[top]=false; outque[top]++; if (outque[top]>node) return false; for (int k=head[top];k!=-1;k=edges[k].next) { if ( dist[edges[k].to]==INF||dist[edges[k].to]>dist[top]+edges[k].w ) { dist[edges[k].to]=dist[top]+edges[k].w; if (!visit[edges[k].to]) { visit[edges[k].to]=true; que.push(edges[k].to); } } } } return true; } int max_short_path(int u) { int ans=0; SPFA(u); for (int i=0;i<node;i++) ans=max(ans,dist[i]); return ans; } }; class GameOnABoard{ private: CSPFA sol; int n,m; bool xycheck(int x,int y){ if (x>=0&&x<n&&y>=0&&y<m) return true; return false; } public: int optimalChoice(vector<string> cost) { int ans; n=cost.size(); m=cost[0].size(); sol.init(n*m); for (int i=0;i<n;i++) { for (int j=0;j<m;j++) { for (int k=0;k<4;k++) { int x=i+direct[k][0]; int y=j+direct[k][1]; if (xycheck(x,y)) sol.addedge(i*m+j,x*m+y,cost[x][y]-'0'); } } } ans=INF; for (int i=0;i<n;i++) { for (int j=0;j<m;j++) { int t=cost[i][j]-'0'; ans=min(ans,sol.max_short_path(i*m+j)+t); } } return ans; } };-----------------