C语言任务整理

 

指针

/*
 3.有一个数组 int any[length],要求写一个函数:
 int * function (int *k, int size);
 将 any 中的 0 都移至数组末尾,将非 0 的移至开始(保持原来的顺序不变)
 例如:
 any 原来是: 1,0,7,9,0,-3, 5
 经过 function 处理后为: 1,7,9,-3,5, 0,0
 */

#include <stdio.h>

int t = 0, z = 0,flag = 0;

int *function (int *,int );
int main()
{
    int n,i;
    int any[100000];
    
    scanf("%d",&n);
    for (i = 0; i < n-1; i++)
        scanf("%d,",&any[i]);
    scanf("%d",&any[n-1]);
    function (any ,n);
}

int *function(int *k, int size)
{
    int i;
    
    for (i = 0; i < size ;i++)
        if (*(k+i) != 0)
        {
            printf("%d",*(k+i));
            i++;
            flag = 1;
            break;
        }
    for (; i < size ;i++)
    {
        if (*(k+i) != 0)
        {
            printf(",%d",*(k+i));
            flag = 1;
        }
    }
    if (flag == 0)
    {
        for (i = 0; i < size ;i++)
        {
            if (*(k+i) == 0)
            {
                printf("%d",*(k+i));
                i++;
                break;
            }
        }
    }
    
    if (flag == 1)
        i = 0;
    
    for (; i < size ;i++)
    {
        if (*(k+i) == 0)
            printf(",%d",*(k+i));
    }
    
    return k;
}
孵化器2.3

文件

/*
 使用 C 语言在 F 盘中创建文件 input.txt(用 C 语言写入一组字符) 和 output.c
 然后,从 F:\\input.txt 中读入一组字符,存放在字 符数组 a 中,并对该组字符进行排序,最后将排好序的这组字符送
 入磁盘文件 F:\\output.c 中保存,同时在屏幕上显示排序后的字符。
 */

#include <stdio.h>
#include <stdlib.h>

char s[10000];
int n,i;

void Scanf(void);
void Sort(void);
void Put(void);

int main()
{
    Scanf();
    Sort();
    Put();
    return 0;
}

void Scanf(void)
{
    FILE *fp;
    //if (!(fp = fopen("/Users/mengyue/Desktop/input.txt","w")))
    if (!(fp = fopen("F:\\input.txt","w")))
        exit(1);
    char ch = getchar();
    while (ch != EOF)
    {
        fputc(ch,fp);
        ch = getchar();
    }
    fclose(fp);
    
    
    //if (!(fp = fopen("/Users/mengyue/Desktop/input.txt","r")))
    if (!(fp = fopen("F:\\input.txt","r")))
        exit(1);
    s[n++] = fgetc(fp);
    while (s[n-1] != EOF)
    {
        s[n++] = fgetc(fp);
    }
    fclose(fp);
    n--;
}

void Sort(void)
{
    int i,j,k;
    for (i = 0; i < n-1; i++)
    {
        k = i;
        for (j = i+1; j < n; j++)
            if (s[j] < s[k])
                k = j;
        char t = s[k];
        s[k] = s[i];
        s[i] = t;
    }
}

void Put()
{
    FILE *fp;
    int cnt = 0;
    
    //if (!(fp = fopen("/Users/mengyue/Desktop/output.c","w")))
    if (!(fp = fopen("F:\\output.c","w")))
        exit(1);
    char ch = s[cnt++];
    while (cnt != n)
    {
        fputc(s[cnt],fp);
        ch = s[cnt++];
    }
    fclose(fp);
}
科协2.3
/*
 编写程序实现下面功能:将一行字符中的每个单词的第一个字母改成大写,并将处理结 果保存在文件”d:\\program\\result.txt”中。
 
 */
#include <stdio.h>
#include <stdlib.h>

char s[100000];

void Put(void);

int main()
{
    char *p = s;
    int i;
    
    gets(s);
    s[0] -= 32;
    
    for (i = 1; *(p+i) != '\0'; i++)
        if (*(p+i-1) == 32)
            s[i] -= 32;
    Put();
}

void Put()
{
    FILE * fp;
    int i;
    
    //if (!(fp = fopen("/Users/mengyue/Desktop/output.c","w")))
    if (!(fp = fopen("d:\\program\\result.txt","w")))
        exit(1);
    
    for (i = 0; s[i] != '\0'; i++)
        fputc(s[i],fp);
    
    fclose(fp);
}
孵化器3.1
/*
设计一个程序,读入给定的电池数据文件,提取出其中的 v1~v18 组电池电压数据,并计算每行的总电压,输出“行号 总电压”。
程序仅需进行一个文件的计算,群文件中会提供一个示例 文件,但此文件仅供参考格式,数据及数据组数没有参考意义。
文件绝对路径:/home/RunSpace/4011.txt 文件权限为只读
输入:无
输出:1、格式为“行号(及 IDX) 总电压”,每行数据占 一行;
2、总电压格式输出为三位小数。
*/

#include <stdio.h>

char s[1000];
double x = 0,sum = 0;
int cnt = 0;
int main()
{
    FILE *fp;
    fp = fopen("/home/RunSpace/4011.txt","r");
    int i;
    for (i = 0; i < 34; i++)
        fscanf(fp,"%s",s);
    
    while (fscanf(fp,"%s",s) != EOF)
    {
        sum = 0;
        for (i = 0; i < 9; i++)
        {
            fscanf(fp,"%s",s);
        }
        for (i = 0; i < 18; i++)
        {
            fscanf(fp,"%lf",&x);
            sum += x;
        }
        cnt ++;
        printf("%d %.3f\n",cnt,sum);
        for (i = 0; i < 6; i++)
        {
            fscanf(fp,"%s",s);
        }
    }
    fclose(fp);
    return 0;
}
智能车4.1 计算电池电压

结构体

/*
利用结构数组处理多个学生信息。假设学生信息包括学号、姓名、3 门课的成绩,计算每 个学生的总分,并按总分从高到低进行输出。
例:
Input
先输入一个整数 n,表示有 n 个学生的信息。
接着输入每个学生的学号、姓名以及 3 门课程的成绩。
Output
输出每个学生的学号、姓名以及总分。每个学生的信息占据一行。
*/

#include <stdio.h>

int n;
struct
{
    int number;
    char name[20];
    int score[3];
    int sum;
} Student[100],t;

void Scanf(void);
void Sort(void);
void Print(void);

int main()
{
    Scanf();
    Sort();
    Print();
}

void Scanf(void)
{
    int i;
    scanf("%d",&n);
    
    for (i = 0; i < n; i++)
    {
        scanf("%d",&Student[i].number);
        getchar();
        gets(Student[i].name);
        scanf("%d",&Student[i].score[0]);
        scanf("%d",&Student[i].score[1]);
        scanf("%d",&Student[i].score[2]);
        Student[i].sum = (Student[i].score[0]+Student[i].score[1]+Student[i].score[2]);
    }
}

void Sort(void)
{
    int i,j,k;
    for (i = 0; i < n-1; i++)
    {
        k = i;
        for (j = i+1; j < n; j ++)
            if (Student[j].sum > Student[k].sum)
                k = j;
        t = Student[i];
        Student[i] = Student[k];
        Student[k]= t;
    }
}

void Print(void)
{
    int i;
    
    for (i = 0;i < n; i ++)
    {
        printf("%d ",Student[i].number);
        printf("%s ",Student[i].name);
        printf("%d\n",Student[i].sum);
    }
}
孵化器3.2
/*
有 N 个学生,每个学生的信息包含学号,姓名,和 M 门课的成绩 即有结构体数组
#define N 30 #define M 5 struct student {
char num[10]; char name[20]; float score[M]; float stu_avg; float cource_avg;
}stu[N]
(2) 利用函数 void input(struct student *p,int n, int m ) 完成数据的输入
(3) 利用函数 void process(struct student *p, int n, int m) 计算每个学生 M 门课的平均成绩;
(4) 利用函数 void output(struct student *p, int n, int m) 将处理结果输出;
*/

#include <stdio.h>
#define N 30
#define M 5

struct student
{
    char num[10];
    char name[20];
    float score[M];
    float stu_avg;
    float cource_avg;
}stu[N];

void input(struct student *p, int n, int m);
void process(struct student *p, int n, int m);
void output(struct student *p, int n, int m);

int main()
{
    input (stu, N, M);
    process(stu, N, M);
    output(stu, N, M);
}

void input(struct student *p, int n, int m)
{
    int i, j;
    for (i = 0; i < n; i++)
    {
        scanf("%s",(p+i)->num);
        getchar();
        gets((p+i)->name);
        for (j = 0; j < m; j++)
            scanf("%f",&(p+i)->score[j]);
    }
}

void process(struct student *p, int n, int m)
{
    int i, j;
    double sum;
    for (i = 0; i < n; i++)
    {
        sum = 0;
        for (j = 0; j < m; j++)
            sum += (p+i)->score[j];
        (p+i)->stu_avg = sum/M;
    }
}

void output(struct student *p, int n, int m)
{
    int i;
    for (i = 0; i < n; i++)
    {
        printf("%s ",(p+i)->num);
        printf("%s ",(p+i)->name);
        printf("%f\n",(p+i)->stu_avg);
    }
}
孵化器3.3

字符串

/*
 词频统计。输入一系列英文单词(单词之间用空格隔开),以输入“end” 作为输入结束的标志。
 统计各单词出现的次数,输出单词和对应的词 频(输入符号时可空格输入)。
 提高:对单词按照英文词典顺序排列后再输出单词和对应的词频;
 */

#include <stdio.h>
#include <string.h>

char c[1000][20];
int main()
{
    int i, j, k, n = 0,cnt = 1;
    char p[1000],q[20];
    
    while (1)
    {
        scanf("%s",c[n++]);
        if (c[n-1][0] == 'e')
        {
            n--;
            break;
        }
    }

    /*sort*/
    for (i = 0; i < n-1; i ++)
    {
        k = i;
        for (j = i+1; j < n; j++)
        {
            if (strcmp(c[j],c[k]) < 0)
                k = j;
        }
        strcpy (q,*(c+i));
        strcpy (p,*(c+k));
        strcpy (*(c+i),p);
        strcpy (*(c+k),q);
        
    }
    
    p[0] = '1' ;
    for (i = 0; i < n; i++)
    {
        if (strcmp(c[i],p) == 0)
            cnt ++;
        else
        {
            if (i != 0)
                printf("%d\n",cnt);
            printf("%-10s  ",c[i]);
            cnt = 1;
            strcpy (p,c[i]);
        }
    }
    printf("%d\n",cnt);
    
    return 0;
}
科协2.2
/*
 输入一串数字,要求删除若干数字后,在原数字顺序不变的情况下,所得的结果最小,再按删 除顺序输出删除的数字
 */

/*思路:如果s[i]>s[i+1]则s[i]可删除。  如果找不到这样的s[i],就从末尾依次删除。*/
#include <stdio.h>
#include <string.h>

char s[100000];
int del[100000]; //是否已经删除
int n, i, cnt = 0,flag = 0;//6315365489423

void Scanf(void);
void delete(void);
void delete1(void);
void Print(void);

int main()
{
    Scanf();
    
    while(cnt < n)
    {
        delete();
        if (cnt == n)
            break;
        if (flag == 0)
        {
            delete1();
            break;
        }
    }
    
    Print();
    
    return 0;
}

void Scanf(void)
{
    printf("请输入需要待处理的数字:");
    scanf("%s",s);
    printf("请输入需要删除的数字的个数:");
    scanf("%d",&n);
}

void delete(void)
{
    flag = 0;
    char *q = s;
    int i, k = 0;
    char pre = '0';
    
    for (i = 0; *(q+i+1) != '\0'; i++)//查找第一个未被删除的数,下标为k
        if (del[i] == 0)
        {
            pre = *(s+i);
            k = i;
            break;
        }
    
    for (i++; *(q+i) != '\0'; i++) //如果pre > s[i],删除pre
    {
        if (del[i] == 1)
            continue;
        if (*(q+i) < pre)
        {
            del[k] = 1;
            cnt++;
            flag = 1;
        }
        if (cnt == n)
            return;
        pre = *(q+i);
        k = i;
    }
}

void delete1(void)
{
    int length = (int)strlen(s), i;
    for (i = length-1; i >=0; i--)
    {
        if (del[i] == 0)
        {
            del[i] = 1;
            cnt ++;
            if (cnt == n)
                break;
        }
    }
}

void Print(void)
{
    int i;
    char *p = s;
    printf("处理结果:");
    for (i = 0; *(p+i) != '\0'; i++)
        if (del[i] == 0)
            printf("%c",*(p+i));
    printf("\n删除的数字:");
    for (i = 0; *(p+i) != '\0'; i++)
        if (del[i] == 1)
            printf("%c",*(p+i));
}
科协2.6 字符串 模拟
/*
给你两个字符串,寻找其中一个字符串是否包含另一个字符串,如果包含,返回包含的起 始位置。
*/

#include <stdio.h>
#include <string.h>

char s1[1000000],s2[1000000],q[1000000],p[1000000];

int fun(char *);

int main()
{
    int i = 0,flag = 0;
    scanf("%s",s1);
    scanf("%s",s2);
    if ((strlen(s1)) > strlen(s2))
    {
        strcpy(q,s1);
        strcpy(p,s2);
        strcpy(s1,p);
        strcpy(s2,q);
    }
    for (; *(s2+i) != '\0'; i++)
    {
        if (*(s2+i) == *(s1))
            if (fun(s2 + i))
            {
                printf("%d",i);
                flag = 1;
                break;
            }
    }
    if (flag == 0) printf("不包含");
    return 0;
}

int fun(char *s2)
{
    int i,flag = 1;
    for (i = 0; *(s1+i) != '\0'; i++)
    {
        if (*(s2+i) != *(s1+i))
        {
            flag = 0;
            break;
        }
    }
    return flag;
}
孵化器2.5 寻找子串位置
/*
数字连接
设有 n 个正整数,将他们连接成一排,组成一个最大的多位整
数。
如:n=3 时,3 个整数 13,312,343,连成的最大整数为 34331213。 如:n=4 时,4 个整数 7,13,4,246 连接成的最大整数为 7424613。 输入描述:
有多组测试样例,每组测试样例包含两行,第一行为一个整数 N(N<=100),第二行包含 N 个数(每个数不超过 1000,空格分开)。 输出描述:
   每组数据输出一个表示最大的整数。
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char s[110][1010];
char a[1010],stra[1010],strb[1010],b[1010];

int main()
{
    int n,i,j,k;
    scanf("%d",&n);
    for (i = 0;i < n;i++)
    {
        scanf("%s",s[i]);
    }
    for (i = 0;i <n-1; i++)
    {
        k = i;
        for (j = i+1; j < n;j++)
        {
            strcpy (stra,s[k]);
            strcat (stra,s[j]);
            strcpy (strb,s[j]);
            strcat (strb,s[k]);
            if (strcmp (stra,strb) < 0)
                k = j;
        }
        strcpy(a,s[i]);
        //strcpy(s[i],s[k]);
        //strcpy(s[k],a);
        strcpy (b,s[k]);
        strcpy (s[i],b);
        strcpy (s[k],a);
    }
    for (i = 0;i < n;i++)
        printf("%s",s[i]);
    return 0;
}
智能车1.7 数字连接
/*
 句子反转
 给定一个句子(只包含字母和空格),将句子中的单词位置反 转,单词用空格分割, 单词之间只有一个空格,前后没有空格。 比如:(1)“hello xiao mi”-> “mi xiao hello” 输入描述:
 输入数据有多组,每组占一行,包含一个句子(句子长度小于 1000 个字符)
 输出描述: 对于每个测试示例,要求输出句子中单词反转后形成的句子
 */
#include <stdio.h>
#include <string.h>

char s[1010];
unsigned long x;
int l,r,i,j,k;
int main()
{
    while (gets(s)!=NULL)
    {
       
        l = r = (int)strlen(s);
        while (l > 0)
        {
            l --;
            if (s[l] == ' ')
            {
                for (i = l+1;i <= r;i++)
                    printf("%c",s[i]);
                printf(" ");
                r = l-1;
            }
        }
        if (l == 0)
            for (i = l; i <= r; i++)
                printf("%c",s[i]);
    }
    return 0;
}
智能车1.6 句子反转
/*(
1、宝石与石头
给定字符串 J 代表石头中宝石的类型,和字符串 S 代表你拥有的
石头。S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥 有的石头中有多少是宝石。
J 中的字母不重复,J 和 S 中的所有字符都是字母。字母区分大 小写,因此"a"和"A"是不同类型的石头。
示例:
输入 1:aA aAAbbbb
输出 1:3
输入 2:z ZZ
输出 2:0
注意:
(1)S 和 J 最多含有 50 个字母。 (2)J 中的字符不重复。
 */

#include <stdio.h>

char s1[60],s2[60];
int d[200];

int main()
{
    int i,ans = 0;
    
    while (scanf("%s%s",s1,s2) != EOF)
    {
        for (i = 0; *(s1+i) != '\0'; i++)
            d[*(s1+i)] ++;
        for (i = 0; *(s2+i) != '\0'; i++)
            ans += d[*(s2+i)];
        
        printf("%d\n",ans);
        
        for (i = 0; *(s1+i) != '\0'; i++)
            d[*(s1+i)] = 0;
        ans = 0;
    }
    return 0;
}


/*
2、独特的电子邮件地址 每封电子邮件都由一个本地名称和一个域名组成,以@符号分隔。 例如,在 [email protected] 中,alice 是本地名称,而 smar
tcar.com 是域名。 除了小写字母,这些电子邮件还可能包含','或'+'。 如果在电子邮件地址的本地名称部分中的某些字符之间添加句
点('.'),则发往那里的邮件将会转发到本地名称中没有点的同一地 址。例如,“[email protected]”和“[email protected]”会 转发到同一电子邮件地址。(请注意,此规则不适用于域名。)
如果在本地名称中添加加号('+'),则会忽略第一个加号后面的 所有内容。这允许过滤某些电子邮件,例如 [email protected] 将 转发到 [email protected]。(同样,此规则不适用于域名。)
可以同时使用这两个规则。
输入电子邮件地址,输出实际收到邮件的电子邮件地址。
示例:
输入 1:[email protected]
输出 1:[email protected]
输入 2:[email protected] 输出 2:[email protected]
输入 3:[email protected]
输出 3:[email protected]
 */

#include <stdio.h>

int main()
{
    char s[1000];
    int i, j;
    
    while (scanf("%s",s) != EOF)
    {
        for (i = 0; *(s+i) != '\0'; i++)
        {
            if (*(s+i) == '.')
                *(s+i) = '0';
            if (*(s+i) == '+')
            {
                for (j = i; *(s+j) != '@'; j++)
                    *(s+j) = '0';
            }
            if (*(s+i) == '@')
                break;
        }
        
        for (i = 0; *(s+i) != '\0'; i++)
            if (*(s+i) != '0')
                printf("%c",*(s+i));
        printf("\n");
    }
}
智能车2.1 2.2
/*
给定一个字符串,找出不含有重复字符的最长子串的长度。
要求:
1、给定字符串最大长度 100,不包含空格等特殊字符;
2、测试输入多组数据,以读取到文件结尾为结束。 输入示例:
输入示例:
abcabcbb
bbbbb
pwwkew
输出示例:
3
1
3
*/

#include <stdio.h>

int main()
{
    char s[110];
    int a[200];
    char *p, *q;
    int ans, maxans;
    while (scanf("%s",s) != EOF)
    {
        for (p = s; *p != '\0'; p++)
            a[*p] = 0;
        maxans = ans = 0;
        for (p = s; *p != '\0'; p++)
        {
            if (a[*p] == 0)
            {
                a[*p] = 1;
                ans ++;
            }
            else
            {
                if (ans > maxans)
                    maxans = ans;
                ans = 1;
                for (q = s; *q != '\0'; q++)
                    a[*q] = 0;
                a[*p] = 1;
            }
        }
        for (p = s; *p != '\0'; p++)
            a[*p] = 0;
        printf("%d\n",maxans);
    }
    return 0;
}
智能车3.1 无重复字符的最长子串

链表

/*
(拓展题)设计 main()函数进行测试。已知一个正整数组成的无序序列,个数未知,但 至少有一个元素,你的任务是建立一个单链表,并使用该链表存储这个正整数序列,然后 将这个链表进行排序,使得排序后的链表为递增序列。正整数的输入用-1 作为结束标志, 注意-1 不算这个正整数序列中的元素(不要统计-1)。在排序的过程中,你可以自己选择 排序算法(冒泡排序、选择排序等),但必须是通过修改结点的指针域来进行排序,而不 是对结点的数据域进行修改。程序结束后要释放所有节点占据的空间。 输入与输出要求:输入一个元素个数未知的正整数序列,以输入“-1”结束,输入“-1” 前至少输入一个正整数。输出经过排序后的链表,每个元素后有一个空格,注意最后一个 元素后只有换行符。
程序运行效果:
Please input a list(end by -1):49 38 65 97 76 13 27 49 -1↙
The new list is:13 27 38 49 49 65 76 97
*/
#include <stdio.h>
#include <stdlib.h>

struct link
{
    int date;
    struct link* next;
}   *pi, *pj, *q, *p, t;

int main()
{
    struct link * head, *ptail, *pnew;
    printf("Please input a list(end by -1):");
    
    /*build*/
    pnew = (struct link*) malloc(sizeof(struct link*));
    scanf("%d",&pnew->date);
    head = ptail = pnew;
    while(1)
    {
        pnew = (struct link*) malloc(sizeof(struct link*));
        scanf("%d",&pnew->date);
        if (pnew->date == -1) break;
        ptail->next = pnew;
        ptail = pnew;
    }
    ptail->next = NULL;
    
    
    /*sort*/
   
    pi = head;
    while (pi->next != NULL)
    {
        pj = pi->next;
        while (pj != NULL)
        {
            if (pi->date > pj->date)
            {
                t = *pi;
                *pi = *pj;
                *pj = t;
                t.next = pi->next;
                pi->next = pj->next;
                pj->next = t.next;
            }
            pj = pj->next;
        }
        pi = pi->next;
    }
    

    /*print*/
    printf("The new list is:");
    for (q = head; q->next != NULL; q = q->next)
    {
        if (q != head)
            free(p);
        printf("%d ",q->date);
        p = q;
    }
    printf("%d\n",q->date);
    free(p);
    free(q);
    
    return 0;
}
孵化器3.5
/*
已知一个正整数组成的无序序列,个数未知,但至少有一个元素,你的任务是建立一个单链表,并使用该链表存储这个正整数 序列,然后将这个链表进行排序,使得排序后的链表为递增序列。
每组数据的输入以-1 作为结束标志,注意-1 不算这个正整数序列 中的元素。结束后输出排序后的正整数序列,以空格间隔(要求 使用链表,会抽查代码)
要求:
1、测试输入多组数据,以读取到文件结尾为结束。
2、输出序列在大括号内部以, 间隔
输入示例:
5 4 3 2 4 7 5 3 4 5 -1
99 77 55 33 11 22 44 66 88 -1
输出示例:
{2, 3, 3, 4, 4, 4, 5, 5, 5, 7}
{11, 22, 33, 44, 55, 66, 77, 88, 99}
*/
#include <stdio.h>
#include <stdlib.h>

struct a
{
    int data;
    struct a *next;
};


int main()
{
    struct a *pnew, *head, *ptail, *i, *j, *k;
    pnew = (struct a*) malloc(sizeof(struct a));
    while(scanf("%d",&pnew->data) != EOF)
    {
        head = ptail = pnew;
        while (1)
        {
            pnew = (struct a*) malloc(sizeof(struct a));
            scanf("%d",&pnew->data);
            if (pnew->data == -1)
            {
                ptail->next = NULL;
                break;
            }
            ptail->next = pnew;
            ptail = pnew;
        }
        for (i = head; i->next != NULL; i = i->next)
        {
            k = i;
            for (j = i->next; j != NULL; j = j->next)
                if (j->data < k->data)
                    k = j;
            int x = k->data;
            k->data = i->data;
            i->data = x;
        }
        printf("{%d",head->data);
        for (i = head->next; i != NULL; i = i->next)
            printf(", %d",i->data);
        printf("}\n");
    }
    return 0;
}
智能车3.3 链表排序

算法

/*
 输入年份(1900 年以后的年份)和月份,查询相应的信息,采用菜单 选择功能:
 输入“1”:闰年查询
 输入“2”:元旦是星期几(用中文输出)
 输入“3”:当前月份有多少个周日
 输入“4”:则选择重新输入年份和月份查询
 输入“end”:程序结束;
 */

#include <stdio.h>

int r,r1,a,i;
int b1,b2,b3,b4;
char str[9];
char str2[][40] = {"","","","","","","",""};
int d[20] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int abc();

int main()
{
    abc();
    return 0;
}

int abc()
{
    int y,m;
    printf("Please input year & month:");
    scanf("%d%d",&y,&m);
    while(1)
    {
        a = (y%400 == 0) || (y%4 == 0 && y%100 != 0);
        r = (y+(y-1)/4-(y-1)/100+(y-1)/400)%7;
        scanf("%s",str);
        if (str[0] == 'e')
            return 0;
        if (str[0] == '1')
            //   if ((yr%400 == 0) || (yr%4 == 0 && yr%100 != 0))// warning:add explicit braces to avoid dangling else
            //   a = yr%400 == 0 || yr%4 == 0 && yr%100 != 0; //warning :'&&'within '||'
        {
            if (a)
                printf("%d是闰年",y);
            else
                printf("%d不是闰年\n",y);
        }//这个if else也要强制加括号。。
        if (str[0] == '2')
        {
            //r = (x-1989)/4;
            //r1 = (x-1990+1+r)%7;
            printf("这年的元旦是星期%s\n",str2[r]);
        }
        if (str[0] == '3')
        {
            b1 = 0;b4 = 0;
            if (a) d[2] = 29;
            else d[2] = 28;
            for (i = 1;i < m;i++)
                b1 += d[i];
            //printf("b1:%d\n",b1);
            b2 = (r+b1)%7; //本月1号
            //printf("b2:%d\n",b2);
            b3 = 1+7-b2;
            if (b2 == 0) b3 = 1;
            while (b3 <= d[m])
            {
                b4 ++;
                b3 += 7;
            }
            printf("这个月共有%d个星期日\n",b4);
        }
        if (str[0] == '4') abc();
    }
}
科协1.1 模拟
/*
 内容:输入一个大于等于 3 且小于 100 的整数 N,输出 N*N 的数字阵。
输入样例 3:
N=5
输出样例 3:
1    2   3   4   5
16  17  18   19  6
15  24  25   20  7
14  23  22   21  8
13  12  11   10  9
 */

#include <stdio.h>
#define N 110

int n;
int a[N][N];
int main()
{
    scanf("N=%d",&n);
    int i = 1,j = 1,r = n,num = 0,k = 1;
    while (1)
    {
        for (k = 1;k <= r;k ++) a[i][j++] = ++num;
        r--;
        j --;   i ++;
        if (num == n*n) break;
        
        for (k = 1;k <= r;k ++) a[i++][j] = ++num;
        j --;   i--;
        if (num == n*n) break;
        
        for (k = 1;k <= r;k ++)a[i][j--] = ++num;
        j++;    i--;
        if (num == n*n) break;
        r --;
        
        for (k = 1;k <= r;k ++) a[i--][j] = ++num;
        j ++;   i++;
        if (num == n*n) break;
    }
    
    for (i = 1;i <= n;i++)
    {
        for (j = 1;j <= n;j++)
        {
            printf("%-5d",a[i][j]);
            if (j == n)
                printf("\n");
        }
    }
    return 0;
}
科协1.2 模拟 数字阵
/*
 题目名称:正整数一定范围内 2-16 进制任意进制转换;
 题目功能:
 (1)输入内容为要转换的数值,输入数值的进制、转换后数值进制
 (2)完成对输入内容检查,
 如:输入数值是否满足输入进制要求,输入进制是 否超过 2-16 范围等
 (3)允许输入字母大小写 (4)实现输入数值按照输入进制、输出进制的转换
*/

#include <stdio.h>
#include <string.h>

int Overflow(char, int);
int Transform1(char *, int);
int Check(char *Num, int t);
void Transform2(int, int);
int CtoI (char);
char ItoC(int);
int Factorial(int, int);

int main()
{
    int Type1,Type2,ans1;
    char Num[1000000];
    printf("请输入你想要转换的数据:");
    gets(Num);
    printf("请输入此进制的类型:");
    scanf("%d",&Type1);
    printf("请输入你需要转换的进制类型:");
    scanf("%d",&Type2);
    if (Check(Num,Type1) == 0)
    {
        printf("输入的数据超出进制范围");
    }
    else
    {
        printf("结果为:");
        ans1 = Transform1(Num,Type1);
     //   printf("(Num)10 = %d\n",ans1);
        Transform2(ans1,Type2);
    }
    return 0;
}

int Check(char *Num, int t)//检查t进制下Num是否合理
{
    int i;
    
    for (i = 0; *(Num + i) != '\0'; i ++)
    {
        if (*(Num+i) >= 'a') *(Num + i) -= 32;
        if (Overflow(*(Num+i),t))
        {
            return 0;
        }
    }
    return 1;
}

int Overflow(char x, int t)
{
    if ('0' <= x && x <= '9')
        x -= 48;
    if ('A' <= x && x <= 'Z')
        x -= 55;
    if (x >= t)
        return 1;
    return 0;
}

int Transform1(char *Num,int t)     //将t进制下Num转化为10进制
{
    int ans = 0,i = 0,length = (int)strlen(Num);
    for (;*(Num+i) != '\0'; i++)
    {
        if (*(Num+i) != '0')
            ans += (Factorial(t,length-(i+1))) * CtoI(*(Num+i));
    }
    return ans;
}

void Transform2(int x, int t)       //将10进制整数x转化为t进制
{
    char Remainder[1000];
    int i = 0;
    while (x != 0)
    {
        Remainder[i] = ItoC (x%t);
        x /= t;
        i++;
    }
    i--;
    for (;i >= 0; i--)
        printf("%c",Remainder[i]);
}

int CtoI(char x)    //将char型x转化为int
{
    if (x >= '0' && x <= '9')
        return (x-48);
    if (x >= 'A' && x <= 'Z')
        return (x-55);
    return 0;
}

char ItoC(int x)    //将int型x转化为char
{
    if (x >= 0 && x <= 9)
        return (x+48);
    if (x >= 10 && x <= 15)
        return (x+55);
    return 0;
}

int Factorial(int down,int up)
{
    int i,ans = 1;
    for (i = 0; i < up; i++)
        ans *= down;
    return ans;
}
科协1.4 模拟 进制转换
/*
 5.在边长为 9 的正方形培养皿中,正中心位置有 m 个细菌。假设细菌的寿命仅一天, 但每天可繁殖 10 个后代,而且这 10 个后代,有两个分布在原来的单元格中,其余的 均匀分布在其四周相邻的八个单元格中。求经过 n(1≤n≤4)天后,细菌在培养皿中的 分布情况。

 输入为两个整数,第一个整数 m 表示中心位置细菌的个数(2 ≤ m ≤ 30),第二 个整数 n 表示经过的天数(1 ≤ n ≤ 4)。
 输出九行九列整数矩阵,每行的整数之间用空格分隔。整个矩阵代表 n 天后细菌在 培养皿上的分布情况。
样例输入
21
样例输出
000000000
000000000
000000000
000222000
000242000
000222000
000000000
000000000
000000000
*/
#include <stdio.h>
#include <string.h>

int a[10][10];
int b[10][10];
int main()
{
    int n,m,i,j,k;
    scanf("%d%d",&m,&n);
    a[5][5] = m;
    for (k = 1;k <= n;k++)
    {
        memcpy(b,a,10*10*sizeof(int));
        for (i = 1;i <= 9 ;i ++)
            for (j = 1; j<= 9;j++)
                if (a[i][j])
                {
                    b[i-1][j-1] += a[i][j];
                    b[i-1][j] += a[i][j];
                    b[i-1][j+1] += a[i][j];
                    b[i][j-1] += a[i][j];
                    b[i][j+1] += a[i][j];
                    b[i+1][j-1] += a[i][j];
                    b[i+1][j] += a[i][j];
                    b[i+1][j+1] += a[i][j];
                    b[i][j] += a[i][j];
                }
        memcpy(a,b,10*10*sizeof(int));
    }
    for (i = 1;i <= 9;i++)
    {
        for (j = 1;j <= 9;j++)
            printf("%d ",a[i][j]);
        printf("\n");
    }
    return 0;
}
孵化器1.5 模拟 细菌繁殖
/*
 某天,小洪的男朋友突然问她,你知道今天是什么日子吗?小洪答不上来。于是她男朋 友闹别扭了。晚上,小洪才想起!啊!今天是 100 天纪念日。哎,要是有一个恋爱日程序 就好了。你能帮助小洪吗? 要求:编写一函数,计算两个日期之间的时间差,并将其值返回。 日期以年、月、日表 示。 “时间差”以天数表示。 注意考虑日期之间的闰年。 函数的输入参数为日期 1 和 日期 2, 函数的返回值为时间差,单位为天数。
 输入描述:
 输入两个日期。
 输出描述:
 输出两个时间的时间差。
 */
#include <stdio.h>
#include <math.h>

int a[15] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int rn(int x)
{
    if ( (x % 400 == 0) || ((x % 4 == 0) && (x % 100 != 0))) return 1;
    return 0;
}
int b229(int m,int d)
{
    if ((m == 1) || ((m == 2) && (d <29))) return 1;
    return 0;
}
int main()
{
    int y1,y11,y2,m1,m2,m11,m22,d1,d2,ans = 0,ans1 = 0, ans2 = 0,c = 0;
    scanf("%d%d%d%d%d%d",&y1,&m1,&d1,&y2,&m2,&d2);
    y11 = y1;m11 = m1; m22 = m2;
    while (y2 > y1)
    {
        ans += 365;
        y1 ++;
    }
    
    ans1 += a[m1]-d1;
    m1 ++;
    while (m1 <= 12)
    {
        ans1 += a[m1];
        m1++;
    }
    
    ans2 += a[m2]-d2;
    m2 ++;
    while (m2 <= 12)
    {
        ans2 += a[m2];
        m2++;
    }
    if (rn(y11) && b229(m11,d1)) c++;
    y11++;
    while (y11<y2)
    {
        if (rn(y11))    c++;
        y11++;
    }
    if (rn(y2) && !b229(m22,d2)) c++;
    ans = ans +ans1-ans2+c;
    
  //  printf("%d %d %d\n",ans,ans1,ans2);
    printf("%d",ans);
    return 0;
}
孵化器1.6 模拟 时间差
~~~
孵化器4.2 模拟 日历
~~~
孵化器4.3 模拟 2048
~~~
孵化器4.4 模拟 数字华容道
/*
 内容:生活中的颜色是由三原色 R,G,B 组成,正常情况下是由 RGB888(24 位即 3 个字节)
 来描述一个像素值,但有时候我们为了缩减图片数据的尺寸采 用RGB565(16位2个字节R 5位,G 6位,B 5位)来描述像素值,
 即只 采用R的高5位,G的高6位,B的高5位然后重新组成RGB数据进行传输。
 请设计一个程序输入、一个 24 位的 RGB888 数据,将数据压缩为 16 位的 RGB565 的格式输出。
 
 提高部分:输入一串 RGB888 图像数据,输出一串压缩完的 RGB565 格式的图 像数据。(提示:数组加位运算)
 例如:
 输入样例:abababababab
 输出样例:ad55ad55
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void d(int n)
{
    int a,b,c;
    a = b = c = n;
    a = a >> 8;
    a = a & 63488;
    b = b >> 5;
    b = b & 2016;
    c = c >> 3;
    c = c & 31;
    printf("%x",(a|b|c));
}

void c(char *s)
{
    char s1[1000];
    int j = 0,num = 0;
    while (strcmp(s,"0") > 0)
    {
        j++;
        strcpy (s1,s);
        *(s1+j) = '\0';
     // puts(s1);
        num = (int)strtol(s1,NULL,16);
       // num = atoi(s1);
       // printf("%d\n\n",num);
        if (num >= 8388608 && num <=16777215)
        {
            //printf("%x\n",num);
            d(num);
            //d(s1);
            //puts(s1);puts("\n");
            s = s+j;
            j = 0;
        }
    }
}
int main()
{
    printf("RGB888:");
    char s[80];
    gets(s);
    printf("RGB565:");
    c(s);
    return 0;
}



/*

#include <stdio.h>
int main()
{
    int n,a,b,c;
    scanf("%x",&n);
    a = b = c = n;
    a = a >> 8;
    a = a & 63488;
    b = b >> 5;
    b = b & 2016;
    c = c >> 3;
    c = c & 31;
    printf("%x",(a|b|c));
}

*/
科协1.3 位运算
/*
输入一个整数,将其低八位设置为 10101110,高八位保留原样,并以十六进制输出该 数。
*/
#include <stdio.h>

int main()
{
    int n;
    scanf("%d",&n);
    n = n & 65454;
    n = n | 174;
    printf("%x",n);
    return 0;
}
孵化器3.4 位运算
https://www.cnblogs.com/liumengyue/p/9973346.html
智能车3.2 位运算
/*
 统计并打印 1 亿以内的所有素数个数,并且打印出 1千万以上 1 亿 以内的所有幸运素数(如 11110111 这样仅有 1 位不同,其它位数 字都相同的素数),直接打印答案无效。
 要求:1 秒内完成得优,时间越短得分越高
 1~5 秒内完成得良
 5~15 秒内完成得及超出 15 秒不算
 */
#include <stdio.h>
#include <stdlib.h>
#define N 100000000

int tag[N];     //tag[i] = 1 代表i不是素数
int prime[N];
int c[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0};

int cnt = 0;

void Prime(void);
int Lucky(int);

int main()
{    
    int i;
    
    Prime();
    
    printf("%d\n",cnt);
    for (i = 168; i < cnt; i++)
        if (Lucky(prime[i]))
            printf("%d ",prime[i]);
    return 0;
}

void Prime(void)    /*  线性筛 */
{
    int i, j;
    tag[0] = tag[1] = 1;
    for (i = 2; i <= N; i++)
    {
        if (tag[i] == 0)
            prime[cnt++] = i;
        for (j = 0; j < cnt; j++)
        {
            if (i*prime[j] > N)
                break;
            tag[i*prime[j]] = 1;
            if (i % prime[j] == 0)
                break;
        }
    }
}

int Lucky(int x)
{
    int a = x%10, b = 10, m;
    c[a] ++;
    x /= 10;
    while (x != 0)
    {
        m = x%10;
        if (m == a)
            c[a] ++;
        if (m != a)
        {
            if (b == 10)
            {
                b = m;
                c[b] ++;
            }
            else
            {
                if (m == b)
                    c[b] ++;
                if (m != b)
                {
                    c[a] = 0;
                    c[b] = 0;
                    return 0;
                }
            }
            
        }
        x /= 10;
    }
    if (c[a] == 1 || c[b] == 1)
    {
        c[a] = 0;
        c[b] = 0;
        return 1;
    }
    c[a] = 0;
    c[b] = 0;
    return 0;
}
科协2.5 智能车4.3 线性筛
/*
 糊涂先生给他的五个朋友写信,他写了五封信,但是当他的朋友收到 信后,都告诉他:“你的信寄错了”。
 假设糊涂先生是随机地往信封 里装信的,请编程计算出现这种情况的概率有多少,并把所有的情况 都列出来。
 */

#include <stdio.h>
#define N 5

int letter[10],mailbox[10];
int ach[10];
int cnt = 0;

int Deliver(int, int);

int main()
{
    Deliver(N,0);
    
    printf("概率为%f\n",cnt/120.0);
    return 0;
}

int Deliver(int m, int n)  //递归 剩余m封信未装,当前在装第n封信
{
    int i, j, flag = 0;     //flag == 0 代表上一步方案不可行
    
    if (m == 0)     //全部装完
    {
        for (i = 0; i < N; i++)
            printf("应投%d但投%d ",i,ach[i]);
        putchar('\n');
        cnt ++;
        return 0;
    }
    
    if (letter[n] == 0)
        for (j = 0; j < N; j++)
            if (mailbox[j] == 0)
                if (n != j)     //不匹配
                {
                    letter[n] = 1;
                    mailbox[j] = 1;
                    ach[n] = j;
                    if (Deliver(m-1,n+1) == 0)
                    {
                        letter[n] = 0;
                        mailbox[j] = 0;
                        flag = 0;
                    }
                    else
                        flag = 1;   //下一步可行
                }
    
    return flag;
}
科协2.4 递归
/*
 编程解决以下问题
 1. 输入三点坐标,判断三点能否组成三角形,若能是什么三角形(锐角、钝角、直角);
 2. 对1中的三角形,求出其外接圆圆心与半径;
 3. 输入若干点,试求出覆盖这几点的覆盖圆的最小半径及其圆心;
 
 思路
 2、数学计算带公式
 3、根据最小圆一定有两个或三个点在圆上,暴力求解。
 */
#include <stdio.h>
#include <math.h>

struct
{
    int x;
    int y;
}point[10000];

double rmin, xmin, ymin;
int n;


void Shape(int, int, int, int, int, int);
int Triangle(int, int, int, int, int, int);
void find(int, int, int, int, int, int, int);
void find1(double, double, double, double);
void find2(void);
int In(double, double, double);

int main()
{
    int x1,x2,x3,y1,y2,y3;
    
    printf("输入三个点\n");
    scanf("%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&x3,&y3);
    if (Triangle(x1,y1,x2,y2,x3,y3))
    {
        Shape(x1, y1, x2, y2, x3, y3);
        find(x1, y1, x2, y2, x3, y3,0);
    }
    else
        printf("不能组成三角形~");
    int i;
    printf("求最小覆盖圆,输入总共的点数\n");
    scanf("%d",&n);
    printf("输入具体的点\n");
    for (i = 0; i < n; i++)
        scanf("%d%d",&point[i].x,&point[i].y);
    rmin = 123456789;
    find2();
    return 0;
}
int Triangle(int x1, int y1, int x2, int y2, int x3, int y3)
{
    if (x1 == x2 && x1 == x3)
        return 0;
    if (y1 == y2 && y1 == y3)
        return 0;
    return 1;
}

void Shape(int x1,int y1,int x2,int y2,int x3,int y3)
{
    double a, b, c, t;
    a = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
    b = sqrt((x3-x1)*(x3-x1) + (y3-y1)*(y3-y1));
    c = sqrt((x2-x3)*(x2-x3) + (y2-y3)*(y2-y3));
    if (b > a)
    {
        t = b;  b = a;  a = t;
    }
    if (c > a)
    {
        t = c;  c = a;  a = t;
    }
    if (a*a > b*b + c*c)
        printf("钝角\n");
    else
        if (a*a < b*b + c*c)
            printf("锐角\n");
    else
        printf("直角\n");
    return;
}

void find(int x1,int y1,int x2,int y2,int x3,int y3,int flag) //寻找三个点的外接圆
{
    double a,b,c,d,e,f,x,y,r;
    a = 2*x2-2*x1;
    b = 2*y2-2*y1;
    c = x2*x2-x1*x1+y2*y2-y1*y1;
    d = 2*x3-2*x1;
    e = 2*y3-2*y1;
    f = x3*x3-x1*x1+y3*y3-y1*y1;
    x = (f*b-e*c)/(d*b-a*e);
    y = (f*a-c*d)/(e*a-b*d);
    r = sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));
    if (r < rmin)
    {
        if (In(r,x,y))
        {
            rmin = r;
            xmin = x;
            ymin = y;
        }
    }
    if (flag != 1)
        printf("外接圆心:(%.2f,%.2f) 半径:%.2f\n",x,y,r);
}

void find2() //寻找最小覆盖圆
{
    int i, j, k;
    for (i = 0; i < n; i++)
        for (j = i+1; j < n; j++)
            for(k = j+1; k < n; k++)
                find(point[i].x,point[i].y,point[j].x,point[j].y,point[k].x,point[k].y,1);
    for (i = 0; i < n; i++)
        for(j = i+1; j < n; j++)
            find1(point[i].x,point[i].y,point[j].x,point[j].y);
    
    printf("圆心:(%.2f,%.2f),半径:%.2f", xmin, ymin, rmin);
}

int In(double r, double x, double y) //判断是否所有点都在以xy为圆心,以r为半径的圆中。
{
    int i;
    for (i = 0; i < n; i++)
        if ((point[i].x-x)*(point[i].x-x)+(point[i].y-y)*(point[i].y-y) > r*r)
            return 0;
    return 1;
}

void find1(double x1,double y1,double x2,double y2)    // 寻找以两个点为直径的外接圆。
{
    double r,x,y;
    r = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))/2;
    x = (x1+x2)/2;
    y = (y1+y2)/2;
    if (r < rmin)
        if (In(r,x,y))
        {
            rmin = r;
            xmin = x;
            ymin = y;
        }
}
科协2.7 数学
/*
 毒草的入侵
 一份自定义大小的草坪,其中有三种土地形式,普通草,毒草,石头。第零个星期, 毒草只有一颗。
 每个星期,毒草会传播到已被毒草占领的格子四面八方的每一个没有石头 的格(包括垂直与水平相邻的和对角线上相邻的格)。
 1 周之后,这些新占领的格又可以把 毒草传播到更多的格里面了。
 草地由一个图片表示。”.”表示草,而”*”表示大石头。
 */

#include <stdio.h>

//结构体 点
struct node
{
    int x, y;
}q[1000];

char a[1000][1000];
int vis[1000][1000];
int xx[10] = {-1,0,1,-1,1,-1,0,1};
int yy[10] = {-1,-1,-1,0,0,1,1,1};

int m, n, x, y, head, tail, mx;

void Scanf(void);
void bfs(int, int);
int isValid(int, int);
void Push(int, int);

int main()
{
    Scanf();
    bfs(x,y);
    printf("%d星期",mx-1);
    return 0;
}

//读入数据
//入口参数:无
//返回:无

void Scanf(void)
{
    int i, j;
    scanf("%d%d%d%d",&m, &n, &x, &y);
    for (i = 1; i <= n; i++)
    {
        getchar();
        for (j = 1; j <=m; j++)
            scanf("%c", &a[i][j]);
    }
}

//bfs
//入口参数:起始坐标
//返回:无
void bfs(int x,int y)
{
    int i, hx, hy;
    Push(x,y);
    vis[x][y] = 1;
    
    while (head <= tail)
    {
        hx = q[++head].x;
        hy = q[head].y;
        for (i = 0; i < 8; i++)
            if (isValid(hx+xx[i],hy+yy[i]))
            {
                Push(hx+xx[i],hy+yy[i]);
                vis[hx+xx[i]][hy+yy[i]] = vis[hx][hy] + 1;
                if (vis[hx+xx[i]][hy+yy[i]] > mx)
                    mx = vis[hx+xx[i]][hy+yy[i]];
            }
    }
}

//向队列q中添加点
//入口参数:坐标
//返回:无

void Push(int x,int y)
{
    q[++tail].x = x;
    q[tail].y = y;
}

//判断点是否有效
//入口参数:坐标
//返回:1或0

int isValid(int x, int y)
{
    if (x>0 && x<=n & y>0 && y<=m)
        if (a[x][y] == '.' && !vis[x][y])
            return 1;
    return 0;
}
科协3.1 搜索
~~~
孵化器4.1 搜索 走迷宫
https://www.cnblogs.com/liumengyue/p/9973346.html
智能车3.5 递归 最大公约数最小公倍数问题
/*冒泡*/

/*选择*/

/*快排*/
排序

数据结构

/*
最大子树和
一株奇怪的花卉,上面共连有 N 朵花,共有 N-1 条枝干将花儿连在一起,并且未修剪时每 朵花都不是孤立的。每朵花都有一个“美丽指数”,该数越大说明这朵花越漂亮,也有“美 丽指数”为负数的,说明这朵花看着都让人恶心。所谓“修剪”,意为:去掉其中的一条 枝条,这样一株花就成了两株,扔掉其中一株。经过一系列“修剪“之后,还剩下最后一 株花(也可能是一朵)。老师的任务就是:通过一系列“修剪”(也可以什么“修剪”都 不进行),使剩下的那株(那朵)花卉上所有花朵的“美丽指数”之和最大。第一行 第一行输入 N 朵花
第二行输入每朵花的美丽指数
输出最大美丽指数和
*/

#include <stdio.h>

//结构体  边
struct Edge
{
    int to,next;
}e[1000];

int val[1000];
int head[1000];

int cnt, flag = 0;
void ins(int, int);
void dp(int);
int max(int, int);

int main()
{
    int n, i, mx;
    scanf("%d",&n);
    for (i = 1; i <= n; i++)
    {
        scanf("%d",&val[i]);
        if (val[i] >=0)
            flag = 1;
    }
    
    if (flag == 1)
    {
        for (i = n; i > 1; i--)
            ins(i/2,i);
        dp(1);
    }
    
    mx = val[1];
    for (i = 1; i <= n; i++)
    {
        if (val[i] > mx)
            mx = val[i];
    }
    printf("%d",mx);
    return 0;
}

//加边u->v
//入口参数:起点终点
//返回:无
void ins(int u,int v)
{
    e[++cnt].to = v;    e[cnt].next = head[u];  head[u] = cnt;
}

//求以x为根二叉树的最大值
//入口参数:节点x
//返回:无
void dp(int x)
{
    int v, i;
    for (i = head[x]; i; i = e[i].next)
    {
        v = e[i].to;
        dp(v);
        val[x] = max(val[x],val[x] + val[v]);
    }
    if (val[x] < 0)
        val[x] = 0;
}

//求最大值
//入口参数:变量x,y
//返回:最大值
int max(int x, int y)
{
    if (x>y)
        return x;
    return y;
}



#include <stdio.h>

int val[1000];
int ch[1000][2];

void Build(int);
int max(int, int, int, int, int);

int main()
{
    int n, i, mx, flag = 0;//flag = 0,全为负数
    scanf("%d",&n);
    for (i = 1; i <= n; i++)
    {
        scanf("%d",&val[i]);
        if (val[i] > 0)
            flag = 1;
    }
    Build(n);
    if (flag == 1)
    {
        for (i = n/2; i>=1; i--)
        {
            val[i] = max(val[i],val[i] + val[ch[i][0]],val[i] + val[ch[i][1]],
                         val[i] + val[ch[i][0]] + val[ch[i][1]], 0);
        }
    }
    mx = val[1];
    for (i = 1; i < n ; i++)
        if (val[i] > mx)
            mx = val[i];
    printf("%d",mx);
    return 0;
}

//建立二叉树
//入口参数:节点数量
//返回:无
void Build(int n)
{
    int i;
    for (i = 1; 2*i+1 <= n; i++)
    {
        ch[i][0] = 2*i;
        ch[i][1] = 2*i+1;
    }
    if (n%2 == 0)
        ch[n/2][0] = n;
}

//求最大值
//入口参数:变量
//返回:最大值
int max(int x1, int x2, int x3, int x4, int x5)
{
    int t = x1;
    if (x2 > t) t = x2;
    if (x3 > t) t = x3;
    if (x4 > t) t = x4;
    if (x5 > t) t = x5;
    return t;
}
科协3.2 二叉树 树形DP
https://www.cnblogs.com/liumengyue/p/9973346.html
智能车3.6 栈 计算器
/*
24点plus
使用逆波兰表达式的方法计算 24 点中的算式,输入 4 个数字,输出最接近 24 点的答案,如果有两个同样接近的,输出较 小的一个。
数字的顺序可以改变,可以使用加减乘除参与运算。 有多组数据参与运算,每组数据占一行。
输入:每行 4 个数字,以空格间隔
输出:最接近 24 的数字,每组输出占一行,结果保留 3 位小数
输入示例:
10 18 20 15
15 3 5 14
4 16 13 4
14 15 4 8
19 16 4 2
输出示例:
24.000
24.000
23.250
23.286
23.125
*/

#include <stdio.h>
#include <string.h>
#include <math.h>
#define eps 1e-8

char a[10], b[10], c[10], d[10],s[100];
char operate[4] = {'+','-','*','/'};
int fin[1000];
double dig[1000];  //数字栈
char ope[1000];  //运算符栈
int pri[1000];  //存储运算符优先级

int Create(char[], char[], char[], char[], char, char, char);
int Calculate(char *);
int getdig(int, int);
double cal(double, double, char);
int FullArray(int, int, int);
void pop(void);

double min;
int flag,flagless = 0;
int digtop, opetop;

int main()
{
    int i, j, k;
    
    pri['+'] = pri['-'] = 0;
    pri['*'] = pri['/'] = 1;
    
    while(scanf("%s",a) != EOF)
    {
        flag = flagless = 0;
        min = 1000;
        scanf("%s%s%s",b, c, d);
        getchar();
        for (i = 0; i < 4; i++)
        {
            if (flag == 1)
                break;
            for (j = 0; j < 4; j++)
            {
                if (flag == 1)
                    break;
                for (k = 0; k < 4; k++)
                {
                    if (FullArray(i,j,k) == 1)
                    {
                        printf("24.000\n");
                        flag = 1;
                        break;
                    }
                }
            }
        }
        if (flag == 0)
        {
            if (flagless == 1)
                printf("%.3f\n",24-min);
            else
                printf("%.3f\n",24+min);
        }
    }
}


//构造由abcdijk组成的中缀表达式
//入口参数:运算符
//返回:中缀表达式是否构成了24点
int Create(char a[], char b[], char c[],char d[],char i, char j, char k)
{
    int l;
    for (l = 0; *(s+l) != '\0'; l++)
        *(s+l) = '\0';
    strcpy(s,a);
    s[strlen(s)] = i;
    strcat(s,b);
    s[strlen(s)] = j;
    strcat(s,c);
    s[strlen(s)] = k;
    strcat(s,d);
    //printf("%s=",s);
    if(Calculate(s) == 1)
        return 1;
    return 0;
}


//计算s的值
//入口参数:中缀表达式
//返回:是否构成24点
int Calculate(char *s)
{
    digtop = opetop = 0;  //栈顶指针
    int i, x, neg = 0; // neg == 1 负数
    for (i = 0; *(s+i) != '\0'; i++)
    {
        if (fin[i] == 0)    //fin[i] = 1 表示第i位处理完毕
        {
            if (s[i] >= '0' && s[i] <= '9') //数字直接入栈
            {
                x = getdig(i, neg);
                neg = 0;
                dig[++digtop] = (double)x;
            }
            else
            {
                // 两个符号相连,或者第一个字符是符号,证明遇到负数
                if((i>0 && (!(s[i-1] >= '0' && s[i-1] <= '9')))||(i == 0))
                    neg = 1;
                else
                {
                    if (opetop == 0)    //运算符栈为空直接入栈
                        ope[++opetop] = s[i];
                    else
                    {
                        while (pri[ope[opetop]] >= pri[s[i]] && opetop > 0)
                            pop();
                        ope[++opetop] = s[i];
                    }
                }
            }
            
        }
    }
    
    while (opetop > 0)
        pop();
    
    if (fabs(dig[digtop]-24) < eps)     //找到24点
        return 1;
    if (fabs(dig[digtop]-24) < min)
    {
        min = fabs(dig[digtop]-24);
        if (dig[digtop] < 24)
            flagless = 1;
        else
            flagless = 0;
    }
    //printf("%.3f\n",dig[digtop]);
    if (fabs(dig[digtop]-24) == min)
        if (dig[digtop] < 24)
            flagless = 1;
    
    for (i = 0; *(s+i) != '\0'; i++)
        fin[i] = 0;
    return 0;
}

//弹出两个元素运算
//入口参数:无
//返回:无
void pop(void)
{
    double a, b;
    char c;
    a = dig[digtop--];
    b = dig[digtop];
    c = ope[opetop--];
    dig[digtop] = cal(a,b,c);
}


//返回从第i位开始的数字
//入口参数:数字的第一个字符在字符串s中的位置i
//返回:数字
int getdig(int i, int neg)
{
    int x = s[i] - 48;
    fin[i] = 1;
    while (1)
    {
        i++;
        if (i == strlen(s))
            break;
        if (*(s+i) < '0' || *(s+i) > '9')
            break;
        fin[i] = 1;
        x *= 10;
        x += s[i] - 48;
    }
    if (neg == 1)
        return x*(-1);
    return x;
}

//计算
//入口参数:数 运算符
//返回:结果
double cal(double x, double y, char c)
{
    switch (c)
    {
        case '+':
            return x+y;
        case '-':
            return y-x;
        case '*':
            return x*y;
        case '/':
            if (x != 0)
                return y/x;
    }
    return -100000;
}



//全排列
//入口参数:运算符
//返回:构成24点返回1
int FullArray(int i, int j, int k)
{
    //a
    if(Create(a,b,c,d,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(a,b,d,c,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(a,c,d,b,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(a,c,b,d,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(a,d,c,b,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(a,d,b,c,operate[i],operate[j],operate[k]) == 1)   return 1;
    //b
    if(Create(b,a,c,d,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(b,a,d,c,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(b,c,d,a,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(b,c,a,d,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(b,d,a,c,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(b,d,c,a,operate[i],operate[j],operate[k]) == 1)   return 1;
    //c
    if(Create(c,a,b,d,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(c,a,d,b,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(c,b,d,a,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(c,b,a,d,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(c,d,a,b,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(c,d,b,a,operate[i],operate[j],operate[k]) == 1)   return 1;
    //d
    if(Create(d,a,b,c,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(d,a,c,b,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(d,b,a,c,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(d,b,c,a,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(d,c,a,b,operate[i],operate[j],operate[k]) == 1)   return 1;
    if(Create(d,c,b,a,operate[i],operate[j],operate[k]) == 1)   return 1;
    
    return 0;
}
智能车4.2 栈 24点
 

猜你喜欢

转载自www.cnblogs.com/liumengyue/p/10063344.html
今日推荐