2018 北京理工大学复试上机 回忆版
北理上机考试没有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 }