大华2018年软件挑战赛初赛题
初赛 十道题,题目此在,主要讲讲自己的思路,这里是前五题。
1.不相邻最大子序和。不相邻所以奇偶分开写状态转移,然后取两者较大值。类似于leetcode中house robber。
#include "stdio.h" #define max(a,b) ((a)>(b)?(a):(b)) int calc(int *nums,int n){ int a=0,b=0,i; for(i=0;i<n;i++){ if(i%2 == 0){ a = max(b,a+nums[i]); }else{ b = max(a,b+nums[i]); } } return max(a,b); } int main(){ int T,i,n,j; scanf("%d",&T); int res[T]; for(i=0;i<T;i++){ scanf("%d",&n); int nums[n]; for(j=0;j<n;j++){ scanf("%d",&nums[j]); } res[i] = calc(nums,n); } for(i=0;i<T;i++){ printf("%d\n",res[i]); } }
2.链表部分翻转。我还是用数组实现的,翻转就是遍历前一半的长度,和后一半换一下。然后在数组分割的每部分调用这个翻转完成。
#include "stdio.h" void reverse(int *arr,int n,int start){ int m=(n+1)/2+start,i,j,tmp; for(i=start;i<m;i++){ j=n+2*start-i-1; tmp=arr[i]; arr[i]=arr[j]; arr[j]=tmp; } } int main(){ int n,i,j,k,l,T,z=0,tmp=0; scanf("%d",&T); int res[1000],kk[10]; for(k=0;k<T;k++){ j=0; scanf("%d",&n); kk[k] = n; int nums[n]; for(i=0;i<n;i++){ scanf("%d",&nums[i]); } scanf("%d",&l); while(j+l<=n){ reverse(nums,l,j); j+=l; } reverse(nums,n-j,j); for(i=0;i<n;i++){ res[z+i]=nums[i]; } z+=n; } for(k=0;k<T;k++){ for(i=tmp;i<kk[k]+tmp;i++){ printf("%d ",res[i]); } tmp+=kk[k]; printf("\n"); } }
3.霍夫曼编码,这里有参考网上的算法代码,参考地址,也不用造轮子啦。
#include<stdio.h> #include<stdlib.h> typedef int ElemType; struct BTreeNode { struct BTreeNode* left; struct BTreeNode* right; ElemType data; }; void PrintBTree_int(struct BTreeNode* BT) { if (BT != NULL) { printf("%d", BT->data); if (BT->left != NULL || BT->right != NULL) { printf("("); PrintBTree_int(BT->left); if (BT->right != NULL) printf(","); PrintBTree_int(BT->right); printf(")"); } } } struct BTreeNode* CreateHuffman(ElemType a[], int n) { int i, j; struct BTreeNode **b, *q; b = malloc(n*sizeof(struct BTreeNode)); for (i = 0; i < n; i++) { b[i] = malloc(sizeof(struct BTreeNode)); b[i]->data = a[i]; b[i]->left = b[i]->right = NULL; } for (i = 1; i < n; i++) { int k1 = -1, k2; for (j = 0; j < n; j++) { if (b[j] != NULL && k1 == -1) { k1 = j; continue; } if (b[j] != NULL) { k2 = j; break; } } for (j = k2; j < n; j++) { if (b[j] != NULL) { if (b[j]->data < b[k1]->data) { k2 = k1; k1 = j; } else if (b[j]->data < b[k2]->data) k2 = j; } } q = malloc(sizeof(struct BTreeNode)); q->data = b[k1]->data + b[k2]->data; q->left = b[k1]; q->right = b[k2]; b[k1] = q; b[k2] = NULL; } free(b); return q; } ElemType WeightPathLength(struct BTreeNode* FBT, int len) { if (FBT == NULL) return 0; else { if (FBT->left == NULL && FBT->right == NULL) return FBT->data * len; else return WeightPathLength(FBT->left,len+1)+WeightPathLength(FBT->right,len+1); } } int res[26][100]; void HuffManCoding(struct BTreeNode* FBT, int len,int n,int *idx) { static int a[10]; if (FBT != NULL) { if (FBT->left == NULL && FBT->right == NULL) { int i; res[idx[n-FBT->data]][0]=len; for (i = 0; i < len; i++) res[idx[n-FBT->data]][i+1]=a[i]; } else{ a[len] = 0; HuffManCoding(FBT->left, len + 1,n,idx); a[len] = 1; HuffManCoding(FBT->right, len + 1,n,idx); } } } const int* par = 0; int compare(const void* p1, const void* p2) { int a = *(int*)p1; int b = *(int*)p2; if (par[a] > par[b]) return 1; else if (par[a] == par[b]) return 0; else return -1; } void sort_index(const int ar[], int index[], int num) { par = ar; qsort(index, num, sizeof(int), &compare); } int main() { int T,k,kl=0,z=0; scanf("%d",&T); int rrr[10000],lll[T]; for(k=0;k<T;k++){ int i,l,n=0,j,tmp,midx=0,mm=0,ll=0; int asc[26]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; char s[100]; scanf("%s",s); for(l=0;s[l]!='\0';++l); for(i=0;i<l;i++){ asc[s[i]-65]++; } ElemType* a; struct BTreeNode* fbt; for(i=0;i<26;i++){ if(asc[i]!=0){ n++; } } int idxs[n]; for(j=0;j<n;j++){ mm=0; midx=0; for(i=0;i<26;i++){ if(asc[i]>mm){ mm=asc[i]; midx=i; } } idxs[j]=midx; asc[midx]=0; } a = malloc(n*sizeof(ElemType)); for (i = 0; i < n; i++) a[i]=n-i; fbt = CreateHuffman(a, n); HuffManCoding(fbt, 0, n, idxs); for(i=0;i<l;i++){ tmp = s[i]-65; for(j=1;j<res[tmp][0]+1;j++){ rrr[kl] = res[tmp][j]; kl++; ll++; } } lll[k] = ll; } kl=0; for(k=0;k<T;k++){ for(z=0;z<lll[k];z++){ printf("%d",rrr[z+kl]); } kl+=lll[k]; printf("\n"); } }
4.子串出现次数。也就用比较老土的办法一个个比较过去,如果对应上count+1,对不上就再回到原来后一个位置继续比较。
#include "stdio.h" int pp(char *s1,char *s2,int l1,int l2){ int count=0,i,j=0; for(i=0;i<l1;i++){ if(s1[i]==s2[j]){ j++; if(j==l2){ count++; i=i-j+1; j=0; } }else{ i=i-j; j=0; } } return count; } int main(){ int T,k; scanf("%d",&T); int res[T]; for(k=0;k<T;k++){ int count = 0,i,l1,l2; char s1[100],s2[100]; scanf("%s",&s1); scanf("%s",&s2); for(l1=0;s1[l1]!='\0';++l1); for(l2=0;s2[l2]!='\0';++l2); res[k] = pp(s1,s2,l1,l2); } for(k=0;k<T;k++){ printf("%d\n",res[k]); } }
5.吃金币游戏。这个我也没通过。本人思路是先找第一个点,然后遍历和它连接的下一步可行点,然后每个点在递归运行,这个是dfs主要部分。剪枝的话:如果在两步以外又回到走过的点就是形成环舍去,两步以内或没走过可行;同一路同方向不重复走(考虑他下一个递归讲将和之前完全一模一样)。结果:每次求该路径的金币数,取最大值。
#include "stdio.h" #define max(a,b) ((a)>(b)?(a):(b)) int x=1; int line_his[10000]={0}; int line_dir[10000]; int maxV=0; int check(int n){ int i; for(i=x-2;i>=x-3;i--){ if(line_his[i]==n){ return 1; } } for(i=x-4;i>=0;i--){ if(line_his[i]==n){ return 0; } } return 1; } int get_road(int *arr,int r,int n,int *tmp){ int t=0,i; for(i=0;i<r*3;i+=3){ if(arr[i]==n || arr[i+1]==n){ tmp[t]=arr[i]==n?arr[i+1]:arr[i]; t++; } } return t; } int get_value(int *arr,int r,int n1,int n2){ int i; for(i=0;i<r*3;i+=3){ if(arr[i]==n1 && arr[i+1]==n2){ return arr[i+2]; } if(arr[i]==n2 && arr[i+1]==n1){ return arr[i+2]; } } } int calc_v(int *arr,int r,int p){ int tmp = 0,i; int his[10000]={}; for(i=0;i<x-1;i++){ if(his[line_his[i]*p+line_his[i+1]]!=1){ tmp+=get_value(arr,r,line_his[i],line_his[i+1]); } his[line_his[i]*p+line_his[i+1]]=1; his[line_his[i]+line_his[i+1]*p]=1; } return tmp; } /*int check_all(int p){ int i,j,in=0; for(i=0;i<p;i++){ for(j=0;j<x;j++){ if(i==line_his[j]){ in++; break; } } } if(in==p){ return 1; }else{ return 0; } }*/ int dfs(int *arr,int r,int p,int n){ int i,t,tt; int tmp[10000]; //if(check_all(p)){ tt = calc_v(arr,r,p); maxV = max(maxV,tt); t = get_road(arr,r,n,tmp); for(i=0;i<t;i++){ if(line_dir[n*p+tmp[i]]==1){ continue; } line_his[x]=tmp[i]; line_dir[n*p+tmp[i]]=1; x++; if(check(tmp[i])) dfs(arr,r,p,tmp[i]); line_his[x]=-1; line_dir[n*p+tmp[i]]=-1; x--; } return maxV; } int main(){ int T,k; scanf("%d",&T); int result[T]; for(k=0;k<T;k++){ maxV=0; x=1; int p,r,i,t; scanf("%d",&p); scanf("%d",&r); int arr[r*3]; for(i=0;i<r*3;i++){ scanf("%d",&arr[i]); } result[k] = dfs(arr,r,p,0); } for(k=0;k<T;k++){ printf("%d\n",result[k]); } }
版权声明:本文为原创文章,转载请注明出处和作者,不得用于商业用途,请遵守
CC BY-NC-SA 4.0协议。
赞赏一下