USACO SEC.1.2 No.4 Palindromic Squares
题意:输入一个进制b([2,20]),确定从[1,300]中哪些数的平方在该进制下是回文数
解法:核心部分是将十进制数转换为任意进制数,除x取余,逆序排列
/* ID: lsswxr1 PROG: palsquare LANG: C++ */ #include <iostream> #include <vector> #include <map> #include <list> #include <set> #include <deque> #include <stack> #include <queue> #include <algorithm> #include <cmath> #include <cctype> #include <cstdio> #include <iomanip> #include <cmath> #include <cstdio> #include <string> #include <fstream> using namespace std; ///宏定义 const int INF = 1000000000; const int MAXN = 15; const int maxn = MAXN; ///全局变量 和 函数 #define USACO #ifdef USACO #define cin fin #define cout fout #endif ////////////////////////////////////////////////////////////////////////// int b; stack<int> stk, origin, square; queue<int> que; char str[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int main() { #ifdef USACO ofstream fout ("palsquare.out"); ifstream fin ("palsquare.in"); #endif ///变量定义 while(cin >> b) { for (int i = 1; i <= 300; i++) { bool flag = true; while (!origin.empty()) origin.pop(); while (!square.empty()) square.pop(); while (!stk.empty()) stk.pop(); while (!que.empty()) que.pop(); int k = i * i; int o = i; while (o != 0) { int yuu = o % b; origin.push(yuu); o /= b; } while (k != 0) { int yu = k % b; stk.push(yu); que.push(yu); square.push(yu); k /= b; } while ((!stk.empty()) && (!que.empty())) { int f1, f2; f1 = stk.top(); f2 = que.front(); if (f1 != f2) { flag = false; break; } stk.pop(); que.pop(); } if (flag) { while (!origin.empty()) { int index = origin.top(); cout << str[index]; origin.pop(); } cout << " "; while (!square.empty()) { int index = square.top(); cout << str[index]; square.pop(); } cout << endl; } } } ///结束 return 0; }
官方的解法:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <ctype.h> #include <math.h> /* is string s a palindrome? */ int ispal(char *s) { char *t; t = s+strlen(s)-1; for(t=s+strlen(s)-1; s<t; s++, t--) if(*s != *t) return 0; return 1; } /* put the base b representation of n into s: 0 is represented by "" */ // 进制转换的递归写法,可以借鉴和学习 void numbconv(char *s, int n, int b) { int len; if(n == 0) { strcpy(s, ""); return; } /* figure out first n-1 digits */ numbconv(s, n/b, b); /* add last digit */ len = strlen(s); s[len] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[n%b]; s[len+1] = '\0'; } void main(void) { char s[20]; char t[20]; int i, base; FILE *fin, *fout; fin = fopen("palsquare.in", "r"); fout = fopen("palsquare.out", "w"); assert(fin != NULL && fout != NULL); fscanf(fin, "%d", &base); for(i=1; i <= 300; i++) { numbconv(s, i*i, base); if(ispal(s)) { numbconv(t, i, base); fprintf(fout, "%s %s\n", t, s); } } exit(0); }