北理上機考試沒有oj,是老師念你手輸,所以數據量不會太大。
第一題
輸入一個字符串,輸出該字符串最長回文串的長度和個數(回文串:如果一個字符串中心對稱就是回文串)
注意:大小寫不敏感
AbcBa 5 1
AbaB 3 2
思路:
小數據量直接三重循環暴力枚舉就好。
第二題
給你兩個整數n,m (6<=m<=n<=50),首先把[m,n]區間所有偶數表示成兩個素數之和,然后根據素數出現的個數有多到少依次輸出素數及其出現次數當多個素數出現的次數相同的時候,優先輸出較大的素數。(1不是素數,如果一個偶數可以由兩組素數組成,則都需要統計和單獨輸出)
也是暴力枚舉,輸出有點兒惡心
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 int n,m; 8 int tmp[30][30]; // 數字i的第j種組合中小的那個素數記錄在此 9 int t_cnt[30]; // 每個數字可以由多少對兒素數組成 10 int a_cnt[100]; // 記錄素數i在這個結果中出現了幾次 11 12 void swap(int &a, int &b){ // 數字交換 13 a^=b;b^=a;a^=b; 14 } 15 16 bool my_cmp(int a,int b){ // 出現次數大的考前,次數一樣值大的靠前。 17 return a_cnt[a]>a_cnt[b]||(a_cnt[a]==a_cnt[b]&&a>b); 18 } 19 20 void do_print(int x){ 21 if((x<<1) > m){ // 遞歸邊界,准備輸出 22 int cc=0, ans[50]={0}; 23 for(int i=1;i<100;i++){ 24 if(a_cnt[i]){ 25 ans[cc++] = i; 26 } 27 } 28 sort(ans,ans+cc,my_cmp); // 排序 29 for(int i=0;i<cc;i++){ // 輸出 30 printf("%d %d ", ans[i],a_cnt[ans[i]]); 31 }printf("\n"); 32 } 33 34 for(int i=0;i<t_cnt[x];i++){ // 遍歷該層每一種情況 35 a_cnt[tmp[x][i]]++; 36 a_cnt[(x<<1)-tmp[x][i]]++; 37 do_print(x+1); 38 a_cnt[tmp[x][i]]--; // 恢復現場 39 a_cnt[(x<<1)-tmp[x][i]]--; 40 } 41 } 42 43 int main(){ 44 scanf("%d %d", &n,&m); // 輸入 45 if(m<n)swap(n,m); 46 47 memset(tmp,0,sizeof(tmp)); // 初始化中間數組 48 memset(t_cnt,0,sizeof(t_cnt)); 49 50 bool is_prime[60]; // 篩法 51 memset(is_prime,1,sizeof(is_prime)); 52 int prime[50]={0}, p_cnt=0; 53 for(int i=2;i<=50;i++){ 54 if(is_prime[i]){ 55 prime[p_cnt++]=i; 56 for(int j=2;i*j<=50;j++) 57 is_prime[i*j]=0; 58 } 59 } 60 61 for(int i=n;i<=m;i++){ // 找到每個數字的每種可能 62 if(i&1)continue; // 跳過奇數 63 int x=i>>1; 64 for(int j=0;j<p_cnt&&prime[j]<=x;j++){ // 枚舉每一個小於等於i一半的素數 65 if(is_prime[i-prime[j]]){ // 減去一個素數后還是素數 66 tmp[x][t_cnt[x]++]=prime[j]; // 給這個數字增加一個記錄 67 } 68 } 69 } 70 71 do_print((n+1)>>1); // 從第一個數字開始遞歸輸出 72 73 return 0; 74 }