2010 Asia Fuzhou Regional Contest
A hard Aoshu Problem http://acm.hdu.edu.cn/showproblem.php?pid=3699
用深搜写排列,除法要注意,还有不能有前导零。当然可以5个for,但是如果有很多个,dfs还是好的。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<map> 5 #define mt(a,b) memset(a,b,sizeof(a)) 6 using namespace std; 7 const int M=16; 8 char sa[M],sb[M],sc[M],ha[M],hb[M],op[]="+-*/"; 9 int val[8]; 10 bool use[16]; 11 map<string,bool> mp; 12 string str; 13 bool prezero(char s[]){ 14 if(strlen(s)>1&&!val[s[0]-'A']) return true; return false; 15 } 16 int getint(char s[]){ 17 int res=0; 18 for(int i=0;s[i];i++){ 19 res=(res<<3)+(res<<1)+val[s[i]-'A']; 20 } 21 return res; 22 } 23 int solve(const int &a,const char &ope,const int &b){ 24 if(ope=='+') return a+b; 25 if(ope=='-') return a-b; 26 if(ope=='*') return a*b; 27 if(b&&!(a%b))return a/b; 28 return -1; 29 } 30 void flag(const int &a,const char &ope,const int &b){ 31 sprintf(ha,"%d",a); 32 sprintf(hb,"%d",b); 33 str=(string)ha+ope+(string)hb; 34 mp[str]=true; 35 } 36 void dfs(int t){ 37 if(t==5){ 38 if(prezero(sa)||prezero(sb)||prezero(sc)) return ; 39 int a=getint(sa); 40 int b=getint(sb); 41 int c=getint(sc); 42 for(int i=0;i<4;i++){ 43 if(solve(a,op[i],b)==c){ 44 flag(a,op[i],b); 45 } 46 } 47 return ; 48 } 49 for(int i=0;i<10;i++){ 50 if(!use[i]){ 51 val[t]=i; 52 use[i]=true; 53 dfs(t+1); 54 use[i]=false; 55 } 56 } 57 } 58 int main(){ 59 int t; 60 while(~scanf("%d",&t)){ 61 while(t--){ 62 scanf("%s%s%s",sa,sb,sc); 63 mt(use,0); 64 mp.clear(); 65 dfs(0); 66 printf("%d\n",mp.size()); 67 } 68 } 69 return 0; 70 }
Fermat Point in Quadrangle http://acm.hdu.edu.cn/showproblem.php?pid=3694
全一个点跑不出来,特判一下。
1 #include<cstdio> 2 #include<cmath> 3 const double eps=1e-8; 4 struct point{ 5 double x,y; 6 }p[8]; 7 class Fermatpoint {//多边形的费马点 8 #define Q(x) ((x) * (x)) 9 #define EQU(x, y) (fabs(x - y) < eps) 10 public: 11 point solve(int np, point p[]) {//顶点数np,多边形顶点数组p,返回多边形的费马点 12 double nowx=0,nowy=0,nextx=0,nexty=0; 13 for(int i = 0; i < np; i++) { 14 nowx += p[i].x; 15 nowy += p[i].y; 16 } 17 for(nowx /= np, nowy /= np; ; nowx = nextx, nowy = nexty) { 18 double topx = 0, topy = 0, bot = 0; 19 for(int i = 0; i < np; i++) { 20 double d = sqrt(Q(nowx -p[i].x) + Q(nowy - p[i].y)); 21 topx += p[i].x / d; 22 topy += p[i].y / d; 23 bot += 1 / d; 24 } 25 nextx = topx / bot; 26 nexty = topy / bot; 27 if(EQU(nextx, nowx) && EQU(nexty, nowy)) break; 28 } 29 point fp; 30 fp.x = nowx; 31 fp.y = nowy; 32 return fp; 33 } 34 } gx; 35 double Distance(point p1,point p2) { 36 return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); 37 } 38 int main(){ 39 while(~scanf("%lf%lf",&p[0].x,&p[0].y)){ 40 for(int i=1;i<4;i++){ 41 scanf("%lf%lf",&p[i].x,&p[i].y); 42 } 43 bool out=true; 44 for(int i=0;i<4;i++){ 45 if(p[i].x!=-1||p[i].y!=-1){ 46 out=false; 47 break; 48 } 49 } 50 if(out) break; 51 bool all=true; 52 for(int i=1;i<4;i++){ 53 if(!EQU(p[i].x,p[0].x)||!EQU(p[i].y,p[0].y)){ 54 all=false; 55 break; 56 } 57 } 58 if(all){ 59 puts("0.0000"); 60 continue; 61 } 62 point center=gx.solve(4,p); 63 double ans=0; 64 for(int i=0;i<4;i++){ 65 ans+=Distance(center,p[i]); 66 } 67 printf("%.4f\n",ans); 68 } 69 return 0; 70 }
Computer Virus on Planet Pandora http://acm.hdu.edu.cn/showproblem.php?pid=3695
粘贴代码,有空重写一下。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cctype> 5 #define mt(a,b) memset(a,b,sizeof(a)) 6 using namespace std; 7 const int inf=0x3f3f3f3f; 8 const int MAXPATLEN=1024;/** 模式串长度 */ 9 const int MAXPATNUM=256;/** 模式串数目 */ 10 const int MAXSTRLEN=5100010;/** 文本串长度 */ 11 class ACAuto { /**多串匹配(AC自动机)*/ 12 static const int ALPHALEN = 26; 13 static const int PATLEN = MAXPATLEN; 14 static const int PATNUM = MAXPATNUM; 15 static const int STRLEN = MAXSTRLEN; 16 struct Node { 17 int cnt; 18 Node *fail,*chds[ALPHALEN]; 19 Node() : cnt(0), fail(NULL) { 20 mt(chds,0); 21 }; 22 }*root; 23 int Hash(char a) { 24 return a-'A'; 25 } 26 void build_ACAuto() { 27 Node **que = new Node*[PATNUM*PATLEN]; 28 int f = 0, r = 0; 29 root->fail = root; 30 for (int i = 0; i < ALPHALEN; i++) { 31 Node *chd = root->chds[i]; 32 if (chd == NULL) { 33 root->chds[i] = root; 34 } else { 35 chd->fail = root; 36 que[r++] = chd; 37 } 38 } 39 while (f != r) { 40 Node *now = que[f++]; 41 for (int i = 0; i < ALPHALEN; i++) { 42 Node *chd = now->chds[i]; 43 if (chd != NULL) { 44 chd->fail = now->fail->chds[i]; 45 que[r++] = chd; 46 } else { 47 now->chds[i] = now->fail->chds[i]; 48 } 49 } 50 } 51 delete [] que; 52 } 53 void Insert(char str[PATLEN]) { 54 int str_len = strlen(str); 55 Node *now = root; 56 for (int i = 0; i < str_len; i++) { 57 int cid = Hash(str[i]); 58 if (now->chds[cid] == NULL) now->chds[cid] = new Node(); 59 now = now->chds[cid]; 60 } 61 now->cnt++; 62 } 63 public: 64 ACAuto(char pat_list[PATNUM][PATLEN], int list_len) { 65 root = new Node(); 66 for (int i = 0; i < list_len; i++) { 67 Insert(pat_list[i]); 68 } 69 build_ACAuto(); 70 } 71 /** * 计算文本串中匹配所有模式串的次数之和(直接传入文本串) * @param 模式串 * @return 匹配次数 */ 72 int match_times(char str[STRLEN]) { 73 int str_len = strlen(str); 74 int times = 0; 75 Node *now = root; 76 for (int i = 0; i < str_len; i++) { 77 now = now->chds[Hash(str[i])]; 78 times += now->cnt; 79 Node *tmp = now; 80 while (tmp != root) { 81 times += tmp->cnt; 82 tmp = tmp->fail; 83 } 84 } 85 return times; 86 } 87 /** * 计算文本串中匹配所有模式串的次数之和(在函数内逐字符读入文本串) * @return 匹配次数 */ 88 int match_times() { 89 int times = 0; 90 char c; 91 Node *now = root; 92 while (c = getchar(), !isalpha(c)); 93 do { 94 now = now->chds[Hash(c)]; 95 times += now->cnt; 96 Node *tmp = now; 97 while (tmp != root) { 98 times += tmp->cnt; 99 tmp = tmp->fail; 100 } 101 } while (c = getchar(), isalpha(c)); 102 return times; 103 } 104 /** * 计算文本串中匹配到的模式串数目(直接传入文本串。将破坏结点的cnt信息!) * @return 匹配次数 */ 105 int match_keynum(char str[STRLEN]) { 106 int str_len = strlen(str); 107 int times = 0; 108 Node *now = root; 109 for (int i = 0; i < str_len; i++) { 110 now = now->chds[Hash(str[i])]; 111 Node *tmp = now; 112 while (tmp != root && tmp->cnt != -1) { 113 times += tmp->cnt; 114 tmp->cnt = -1; 115 tmp = tmp->fail; 116 } 117 } 118 return times; 119 } 120 /** * 计算文本串中匹配到的模式串数目(在函数内逐字符读入文本串。将破坏结点 * 的cnt信息!) * @return 匹配次数 */ 121 int match_keynum() { 122 int times = 0; 123 char c; 124 Node *now = root, *tmp; 125 while (c = getchar(), !isalpha(c)); 126 do { 127 now = now->chds[Hash(c)]; 128 tmp = now; 129 while (tmp != root && tmp->cnt != -1) { 130 times += tmp->cnt; 131 tmp->cnt = -1; 132 tmp = tmp->fail; 133 } 134 } while (c = getchar(), isalpha(c)); 135 return times; 136 } 137 }; 138 char g[MAXPATNUM][MAXPATLEN]; 139 char op[MAXSTRLEN]; 140 char str[MAXSTRLEN]; 141 int main() { 142 int t,n; 143 while(~scanf("%d",&t)) { 144 while(t--){ 145 scanf("%d",&n); 146 for(int i=0; i<n; i++) { 147 scanf("%s",g[i]); 148 } 149 scanf("%s",op); 150 int ls=0; 151 for(int i=0;op[i];){ 152 if(isalpha(op[i])){ 153 str[ls++]=op[i++]; 154 continue; 155 } 156 if(op[i]=='['){ 157 int sum=0; 158 int j; 159 for(j=i+1;op[j];j++){ 160 if(!isdigit(op[j])) break; 161 sum*=10; 162 sum+=op[j]-'0'; 163 } 164 for(int k=0;k<sum;k++){ 165 str[ls++]=op[j]; 166 } 167 i=j+2; 168 } 169 } 170 int ans=0; 171 str[ls]=0; 172 ACAuto gx(g,n); 173 ans+=gx.match_keynum(str); 174 for(int i=0,j=strlen(str)-1;i<j;i++,j--){ 175 swap(str[i],str[j]); 176 } 177 ans+=gx.match_keynum(str); 178 printf("%d\n",ans); 179 } 180 } 181 return 0; 182 }
Selecting courses http://acm.hdu.edu.cn/showproblem.php?pid=3697
枚举时间加贪心选择终点靠前的,由于后台测试数据大于了题目描述,所以程序需具备鲁棒性。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int M=512; 7 struct point{ 8 int x,y; 9 friend bool operator <(const point &a,const point &b){ 10 return a.y<b.y; 11 } 12 }p[M]; 13 bool use[M]; 14 int main(){ 15 int n; 16 while(~scanf("%d",&n),n){ 17 int big=0; 18 for(int i=0;i<n;i++){ 19 scanf("%d%d",&p[i].x,&p[i].y); 20 p[i].x*=2; 21 p[i].y*=2; 22 big=max(big,p[i].y); 23 } 24 sort(p,p+n); 25 int ans=0; 26 for(int s=0;s<10;s++){ 27 mt(use,0); 28 for(int now=s;now<big;now+=10){ 29 for(int i=0;i<n;i++){ 30 if(!use[i]&&p[i].x<now&&now<p[i].y){ 31 use[i]=true; 32 break; 33 } 34 } 35 } 36 int sum=0; 37 for(int i=0;i<n;i++){ 38 if(use[i]) sum++; 39 } 40 ans=max(ans,sum); 41 } 42 printf("%d\n",ans); 43 } 44 return 0; 45 }
end