练手c语言算法一

Posted by 甘家城 on 2018-05-06 Viewed times

大华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协议。

支付宝打赏 微信打赏

赞赏一下