评论区已开启

评论区已经开始试运行,由于没有通知功能,所以我并不能及时的知道你们的评论,而我又很难有空去翻每一篇文章的评论区,看是否有新的问题,所以希望有问题的评论完后可以QQ和我说一下,谢谢。

汉英词典

前言:

我的大一下学期实训项目是好记星移动词典,基本功能是已知中文找英文,已知英文找中文,还要词典词条的增删查改,由于前俩天我就实现了这些功能,于是在之后我又增添了一个登录系统,虽然好像用处不大,但也还是我第一次写这种多文件互动的项目,写的比较用心,下面将附上项目源代码,和文件下载链接(文件是公开在本人的Github上的,有需要的可以随时取用,其中有7个文件,只要全都下载时,项目才能正常运行,且项目是通过main.c启动的)。

运行效果图:

image-20211029005243741

Main.c

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include "function.h"
#include "dictionary.c"  


int main(int argc,char **argv)
{
    printf("\033[;36;5m ******************************************** \033[0m\n");
    printf("\033[;36;5m *               电子词典项目               * \033[0m\n");
    printf("\033[;36;5m ******************************************** \033[0m\n");
    printf("\033[;36;5m *     1. 注册     2. 登录     3. 退出      * \033[0m\n");
    printf("\033[;36;5m ******************************************** \033[0m\n");
    int choice,flag;
    char FILENAME[20]="user.txt";
    read(user,&numofuser,FILENAME);
    printf("请输入:");
    scanf("%d",&choice);
    switch (choice)
    {
    case 1:sign_in(&numofuser,FILENAME,user);
        break;
    case 2:login(&numofuser,user);
        break;
    case 3:printf("\033[;31;5m   即将退出,欢迎您再次使用!  \033[0m\n");
        break;
    default:printf("\033[;31;5m   输入错误,请重新输入!!!  \033[0m\n");
        break;
    }

    return 0;
}

//统计函数
void read(struct userlist user[],int *numofuser,char filename[]){
    FILE *fp;
    fp=fopen(filename,"r");
    if(fp!=NULL){
        while(!feof(fp)){
            fscanf(fp,"%s %s %d",&user[*numofuser].name,&user[*numofuser].pwd,&user[*numofuser].numofmemwd);
            (*numofuser)++;
        }
    }else{
        printf("\033[;31;5m文件读取失败!!! \033[0m\n");
    }
    fclose(fp);
}

//注册函数
void sign_in(int *numofuser,char filename[],struct userlist user[]){
    char keyn[10],keyp1[20],keyp2[20];
    printf("用户名:");
    scanf("%s",&keyn);
    for(int i=0;i<*numofuser;i++){
        if(strcmp(user[i].name,keyn)==0){
            printf("\033[;31;5m    该用户已经注册,请登录!\033[0m\n");
            sign_in(&(*numofuser),filename,user);
            return;
        }
    }
    printf("密  码:");
    int i = 0;
    char c;
    while (1)
    {
        //getch()这个函数是一个不回显函数,当用户按下某个字符时,函数自动读取,无需按回车
        //函数用途:从控制台读取一个字符,但不显示在屏幕上
        c = getch();
        //如果按下Esc键可以退出
        if((c-48) == (-21)){
            printf("\n\033[;31;1m      退出成功!     \033[0m\n");
                return;
        }
        //windows平台下按下回车(ENTER)键会产生两个转义字符 \r\n,因此getch返回13(\r),
        //                而'\n‘的的转义字符无法读取,因此无法通过判断'\n'的方式结束输入,
        //可以通过读取第一个转义字符进行判断结束输入
        if (c == '\r')//按下回车键时结束输入,退出
        {
            keyp1[i] = '\0';
            break;
        }
        if (c == '\b')//遇到退格键时(←Backsapce)
        {
            //当没有输入密码时,即输入的密码为空时,不进行任何操作
            //即输入的密码不为空时,对显示的字符进行退格
            if (i > 0) 
            { 
                i--;
                //对显示的字符进行退格,两个\b之间存在一个空格
                printf("\b \b");
                        
                keyp1[i] = '\0';//修改输入的字符
                continue;
            }
        }
        else//没有遇到回车键时和退格键时,读取输入的密码存储在字符串password中
        {
            printf("*");    //对输入的密码在控制台显示*号
            keyp1[i] = c;//存储输入的字符        
            if (i < 20) i++;
            else break;
        }
    }
    printf("\n");
    if (i > 0) ;
    else  printf("输入的密码为空");
    printf("请确认密码");
    int j = 0;
    char d;
    while (1)
    {
        d = getch();
        if((d-48) == (-21)){
            printf("\n\033[;31;1m      退出成功!     \033[0m\n");
            return;
        }
        if (d == '\r')
        {
            keyp2[j] = '\0';
            break;
        }
        if (d == '\b')
        {
            if (j > 0) 
            { 
                j--;
                printf("\b \b");    
                keyp2[j] = '\0';
                continue;
            }
        }
        else
        {
            printf("*");
            keyp2[j] = d;    
            if (j < 20) j++;
            else break;
        }
    }
     
    printf("\n");
    if (j > 0) ;
    else  printf("输入的密码为空");
    if(strcmp(keyp1,keyp2)!=0){
        printf("\033[;31;5m   两次输入密码不一致,请重新输入! \033[0m\n");
        sign_in(&(*numofuser),filename,user);
    }
    int flag=0;   
    strcpy(user[*numofuser].name,keyn);
    strcpy(user[*numofuser].pwd,keyp1);
    user[*numofuser].numofmemwd=0;
    (*numofuser)++;
    FILE *fp;
    fp=fopen(filename,"w");
    if(fp!=NULL){
        for(int k=0;k<(*numofuser)-1;k++){
            fprintf(fp,"%s %s %d\n",user[k].name,user[k].pwd,user[k].numofmemwd);
        }
        fprintf(fp,"%s %s %d",user[*numofuser-1].name,user[*numofuser-1].pwd,user[*numofuser-1].numofmemwd);
    }else{
        printf("文件打开失败\n");
    }
    fclose(fp);
    printf("\n\033[;31;5m      %s,恭喜您,注册成功\033[0m\n",keyn);
    printf("请重新登录!\n");
    login(&(*numofuser),user);
    flag=1;      
    if(flag==0){
        printf("\033[;31;5m注册失败!!!\033[0m\n");
    }
}

//登录函数
void login(int *numofuser,struct userlist user[]){
    char keyn[10],keyp[20];
    while(1){
        printf("用户名:");
        scanf("%s",keyn);
        printf("密  码:");
        int i = 0,flag=0;
        char c;
        while (1)
        {
            c = getch();
            if((c-48) == (-21)){
                printf("\n\033[;31;1m      退出成功!     \033[0m\n");
                return;
            }
            if (c == '\r')
            {
                keyp[i] = '\0';
                break;
            }
            if (c == '\b')
            {
                if (i > 0) 
                { 
                    i--;
                    printf("\b \b");    
                    keyp[i] = '\0';
                    continue;
                }
            }
            else
            {
                printf("*");
                keyp[i] = c;    
                if (i < 20) i++;
                else break;
            }
        }
        printf("\n");
        if (i > 0) ;
        else  printf("输入的密码为空");
        for(int i=0;i<*numofuser;i++){
            if(strcmp(keyn,user[i].name)==0&&strcmp(keyp,user[i].pwd)==0){
                printf("\n\033[;31;1m      %s,恭喜您,登录成功! \033[0m\n",keyn);
                flag=1;
                fakemain(user[i].name);
                return;
            }
        }
        if(flag==0){
            printf("\033[;31;5m     用户名或密码错误,请重新输入!!! \033[0m\n");
        
        }
    } 
}

dictionary.c

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

//本文件的主函数
void fakemain(char name[])
{
    struct entry ent[10000];
    int numofwords = 0, choose;
    char FILEPATH[30] = "new_dictionary.txt";
    search(FILEPATH, ent, &numofwords);
    UI(&numofwords, ent, FILEPATH, &choose, name);
    return;
}

//查询有多少个词条的功能函数
void search(char filepath[], struct entry ent[], int *numofwords)
{
    FILE *fp;
    fp = fopen(filepath, "a+");
    if (fp != NULL)
    {
        while (!feof(fp))
        {
            fscanf(fp, "%s %s", &ent[*numofwords].english, &ent[*numofwords].chinese);
            (*numofwords)++;
        }
    }
    else
    {
        printf("\033[;31;5m文件读取失败!!! \033[0m\n");
    }
    fclose(fp);
}

//英译汉功能函数
void E2C(int *numofwords, struct entry ent[])
{
    char key[20];
    while (1)
    {
        printf("请输入要查询的词(输入0000退出查询):");
        scanf("%s", key);
        if (strcmp(key, "0000") == 0)
        {
            return;
        }
        int flag = 0;
        for (int i = 0; i < *numofwords; i++)
        {
            if (strcmp(key, ent[i].english) == 0)
            {
                printf("\033[;33;5m\"%s\" 的中文释义为:%s\033[0m\n", ent[i].english, ent[i].chinese);
                flag = 1;
                break;
            }
        }
        if (flag == 0)
        {
            printf("\033[;31;5m查无此词!!!\033[0m\n");
        }
    }
}

//汉译英功能函数
void C2E(int *numofwords, struct entry ent[])
{
    char key[20];
    while (1)
    {
        printf("请输入要查询的词(输入0000退出查询):");
        scanf("%s", key);
        if (strcmp(key, "0000") == 0)
        {
            return;
        }
        int flag = 0;
        for (int i = 0; i < *numofwords; i++)
        {
            if (strstr(ent[i].chinese, key) != NULL)
            {
                printf("\033[;33;5m\"%s\" 对应的英文是:\"%s\"\033[0m\n", ent[i].chinese, ent[i].english);
                flag++;
            }
        }
        if (flag == 0)
        {
            printf("\033[;31;5m查无此词!!!\033[0m\n");
        }
    }
}

//删除词条功能函数
void deleteentry(int *numofwords, struct entry ent[], char filepath[])
{
    char key[20];
    printf("请输入要删去的词(输入0000退出删除):");
    scanf("%s", key);
    if (strcmp(key, "0000") == 0)
    {
        return;
    }
    int flag = 0;
    for (int i = 0; i < *numofwords; i++)
    {
        if (strcmp(key, ent[i].english) == 0)
        {
            for (int j = i; j < (*numofwords) - 1; j++)
            {
                ent[j] = ent[j + 1];
            }
            (*numofwords)--;
            FILE *fp;
            fp = fopen(filepath, "w+");
            if (fp != NULL)
            {
                for (int k = 0; k < (*numofwords) - 1; k++)
                {
                    fprintf(fp, "%s %s\n", ent[k].english, ent[k].chinese);
                }
                fprintf(fp, "%s %s", ent[*numofwords].english, ent[*numofwords].chinese);
                printf("\033[;33;5m词条删除成功!\033[0m\n");
            }
            else
            {
                printf("文件读取失败\n");
            }
            fclose(fp);
            flag = 1;
            break;
        }
    }
    if (flag == 0)
    {
        printf("\033[;31;5m查无此词!!!\033[0m\n");
    }
}

//用户操作界面
void UI(int *numofwords, struct entry ent[], char filepath[], int *choose, char name[])
{
    /*操作界面*/
    printf("\n\033[;33;5m*************************************************\033[0m\n");
    printf("\033[;33;5m*                欢迎使用电子词典               *\033[0m\n");
    printf("\033[;33;5m*************************************************\033[0m\n");
    printf("\033[;33;5m*     1.英译汉      2.汉译英     3.删除词条     *\033[0m\n");
    printf("\033[;33;5m*     4.添加词条    5.修改词条   6.背单词       *\033[0m\n");
    printf("\033[;33;5m*               7. 保 存 并 退 出               *\033[0m\n");
    printf("\033[;33;5m*************************************************\033[0m\n");
    printf("\033[;33;5m当前字典一共用%d个单词\033[0m\n", *numofwords);

    //用户输入选择
    printf("请输入:");
    scanf("%d", &(*choose));
    switch (*choose)
    {
    case 1:
        E2C(&(*numofwords), ent);
        UI(&(*numofwords), ent, filepath, &(*choose), name);
        break;
    case 2:
        C2E(&(*numofwords), ent);
        UI(&(*numofwords), ent, filepath, &(*choose), name);
        break;
    case 3:
        deleteentry(&(*numofwords), ent, filepath);
        UI(&(*numofwords), ent, filepath, &(*choose), name);
        break;
    case 4:
        addentry(&(*numofwords), ent, filepath);
        UI(&(*numofwords), ent, filepath, &(*choose), name);
        break;
    case 5:
        modientry(&(*numofwords), ent, filepath);
        UI(&(*numofwords), ent, filepath, &(*choose), name);
        break;
    case 6:reciteword(name,user,ent,&numofuser);
        UI(&(*numofwords), ent, filepath, &(*choose), name);
        break;
    case 7:printf("\033[;31;5m        保存成功,欢迎再次使用!\033[0m\n");
        break;
    default:
        printf("\033[;31;5m输入错误,请重新输入!!!\033[0m\n");
        UI(&(*numofwords), ent, filepath, &(*choose), name);
        break;
    }
    return;
}

//添加词条功能函数
void addentry(int *numofwords, struct entry ent[], char filepath[])
{
    char keye[20], keyc[20];
    printf("请输入要添加的单词(输入0000退出添加):");
    scanf("%s", &keye);
    if (strcmp(keye, "0000") == 0)
    {
        return;
    }
    for (int i = 0; i < *numofwords; i++)
    {
        if (strcmp(ent[i].english, keye) == 0)
        {
            printf("该词已在单词库中!\n");
            return;
        }
    }
    printf("请输入中文释义:");
    scanf("%s", &keyc);
    int flag = 0, tmp;
    for (int i = 0; i < *numofwords; i++)
    {
        if (strcmp(keye, ent[i].english) > 0)
        {
            tmp = i;
        }
        else
        {
            break;
        }
    }
    for (int j = *numofwords - 1; j > tmp; j--)
    {
        ent[j + 1] = ent[j];
    }
    strcpy(ent[tmp + 1].english,keye);
    strcpy(ent[tmp + 1].chinese,keyc);
    (*numofwords)++;
    FILE *fp;
    fp = fopen(filepath, "w");
    if (fp != NULL)
    {
        for (int k = 0; k < (*numofwords) - 1; k++)
        {
            fprintf(fp, "%s %s\n", ent[k].english, ent[k].chinese);
        }
        fprintf(fp, "%s %s", ent[*numofwords - 1].english, ent[*numofwords - 1].chinese);
    }
    else
    {
        printf("文件打开失败\n");
    }
    fclose(fp);
    printf("\033[;33;5m添加成功!!!\033[0m\n");
    flag = 1;
    if (flag == 0)
    {
        printf("添加失败!!!\n");
    }
}

//修改词条功能函数
void modientry(int *numofwords, struct entry ent[], char filepath[])
{
    char key[20], keye[20], keyc[20];
    FILE *fp;
    int flag = 0, tmp;
    do
    {
        printf("请输入要修改的单词(退出修改请输入0000):");
        scanf("%s", key);
        if (strcmp(key, "0000") == 0)
        {
            return;
        }
        for (int i = 0; i < *numofwords; i++)
        {
            if (strcmp(key, ent[i].english) == 0)
            {
                flag = 1;
                for (int j = i; j < (*numofwords) - 1; j++)
                {
                    ent[j] = ent[j + 1];
                }
                (*numofwords)--;
                FILE *fp;
                fp = fopen(filepath, "w");
                if (fp != NULL)
                {
                    for (int k = 0; k < (*numofwords) - 1; k++)
                    {
                        fprintf(fp, "%s %s\n", ent[k].english, ent[k].chinese);
                    }
                    fprintf(fp, "%s %s", ent[*numofwords].english, ent[*numofwords].chinese);
                    break;
                }
            }
        }
        if (flag == 0)
        {
            printf("\033[;31;5m查无此词!!!\033[0m\n");
        }
    } while (!flag);
    printf("请输入修改后的英文和中文(其间请用空格或换行隔开):\n");
    scanf("%s", keye);
    scanf("%s", keyc);
    for (int i = 0; i < *numofwords; i++)
    {
        if (strcmp(ent[i].english, keye) == 0)
        {
            printf("\033[;31;5m该词已在单词库中!\033[0m\n");
            return;
        }
    }
    for (int i = 0; i < *numofwords; i++)
    {
        if (strcmp(keye, ent[i].english) > 0)
        {
            tmp = i;
        }
        else
        {
            break;
        }
    }
    for (int j = *numofwords - 1; j > tmp; j--)
    {
        ent[j + 1] = ent[j];
    }
    strcpy(ent[tmp + 1].english, keye);
    strcpy(ent[tmp + 1].chinese, keyc);
    (*numofwords)++;
    fp = fopen(filepath, "w");
    if (fp != NULL)
    {
        for (int k = 0; k < (*numofwords) - 1; k++)
        {
            fprintf(fp, "%s %s\n", ent[k].english, ent[k].chinese);
        }
        fprintf(fp, "%s %s", ent[*numofwords - 1].english, ent[*numofwords - 1].chinese);
        printf("\033[;33;5m修改完成!\033[0m\n");
    }
    else
    {
        printf("文件打开失败\n");
        return;
    }
    fclose(fp);
}

//背单词功能函数
void reciteword(char name[],struct userlist user[],struct entry ent[],int *numofuser)
{
    int n, choice, station, m;
    FILE *fp;
    for (int i = 0; i < *numofuser; i++)
    {
        if (strcmp(user[i].name, name) == 0)
        {
            station = user[i].numofmemwd;
            m = i;
            printf("\033[;35;5m     您已经背了%d个单词了,继续加油哦~('.')~\033[0m\n", user[i].numofmemwd);
        }
    }
    printf("\n\033[;34;5m*************************************\033[0m\n");
    printf("\033[;34;5m*      1.背新单词    2.复习单词     *\033[0m\n");
    printf("\033[;34;5m*************************************\033[0m\n");
    printf("请输入:");
    scanf("%d", &choice);
    switch (choice)
    {
        case 1:
        {
            printf("请输入这次要背的单词数:");
            scanf("%d", &n);
            for (int i = 0; i < n; i++)
            {
                printf("\033[;33;5m   %s %s\033[0m\n", ent[station + i].english, ent[station + i].chinese);
            }
            printf("\033[;33;5m你是最棒的!~('o')~\033[0m\n");
            user[m].numofmemwd += n;
            fp = fopen("user.txt", "w");
            if (fp != NULL)
            {
                for (int k = 0; k < (*numofuser)-1; k++)
                {
                    fprintf(fp, "%s %s %d\n", user[k].name, user[k].pwd, user[k].numofmemwd);
                }
                fprintf(fp, "%s %s %d", user[*numofuser - 1].name, user[*numofuser - 1].pwd, user[*numofuser - 1].numofmemwd);
            }
                else
            {
                printf("\033[;31;5m文件读取失败!!! \033[0m\n");
            }   
            fclose(fp);
        }
            break;
        case 2:
        {
            printf("请输入这次要复习的单词数:");
            scanf("%d", &n);
            for (int i = 0; i < n; i++)
            {
                printf("\033[;33;5m   %s %s\033[0m\n", ent[station - i - 1].english, ent[station - i - 1].chinese);
            }
            printf("\033[;33;5m你是最棒的!~('o')~\033[0m\n");
        }
            break;
        default:printf("\033[;31;5m输入错误,请重新输入!!!\033[0m\n");
            reciteword(name,user,ent,&(*numofuser));
            break;
    }

}

function.h

#include<stdio.h> 
#ifndef function_h

#define function_h

#define MAXC 20
#define MAXE 20
#define total 10000

struct entry
{
    char english[MAXE+1]; //key 
    char chinese[MAXC+1];
    struct entry *next;
};
struct userlist
{
    char name[10];
    char pwd[20];
    int numofmemwd;
};

struct userlist user[1000];
int numofuser=0;

/*函数声明*/
void search(char filepath[],struct entry ent[],int *numofwords);
void E2C(int *numofwords,struct entry ent[]);
void C2E(int *numofwords,struct entry ent[]);
void deleteentry(int *numofwords,struct entry ent[],char filepath[]);
void UI(int *numofwords,struct entry ent[],char filepath[],int *choose,char name[]);
void addentry(int *numofwords,struct entry ent[],char filepath[]);
void modientry(int *numofwords,struct entry ent[],char filepath[]);
void fakemain(char name[]);
void read(struct userlist user[],int *numofuser,char filename[]);
void sign_in(int *numofuser,char filename[],struct userlist user[]);
void login(int *numofuser,struct userlist user[]);
void reciteword(char name[],struct userlist user[],struct entry ent[],int *numofuser);

#endif

进制转换函数 itoa() 详解

起因

昨晚深夜忽有一人问我一道题怎么写,是道进制转换的题,一开始我以为很简单,但这道题还是花了我一个小时的时间,而且大部分时间都花在了对于c语言itoa()函数的误解。
由该函数的参数列表可知(该函数的定义可以在stdlib.h文件中找到)

char *__cdecl itoa(int _Val,char *_DstBuf,int _Radix) __MINGW_ATTRIB_DEPRECATED_MSVC2005;

该函数可以把一个任意的十进制数转换为任意进制的字符串。而且经过debug我发现这个字符串的存储是从高位到低位。而这和下面题目要实现的目标不相符。因为55经过转换后会变成110111,而不是00000000000000000000000000110111 ,所以我们需要对这个字符串进行移位,使其从低地址到高地址排列。而这一部还是很好实现的,只需要写个循环。当一切准备就绪时,我以为我完成了,但没想到啊,-55的转换结果和目标大相径庭,于是我又debug了一次,发现了原因: itoa()函数最终是通过补码的形式存储结果。但我以为是用源码存储所以我错了,但知道了这个特性后我很快就写出来了正解,但由于我忘了IEEE754浮点数是啥,所以没写这部分。

题目描述

32位机器数,输入一个十进制数,转换为二进制数,显示其原码、反码、补码、移码及IEEE754浮点数。

input 1:

55

output 1:

原码:00000000000000000000000000110111
反码:00000000000000000000000000110111
补码:00000000000000000000000000110111
移码:10000000000000000000000000110111
IEEE754浮点数: 01000010010111000000000000000000

源码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
    int a,flag,tmp;
    scanf("%d",&flag);
    a=(int)abs(flag);
    char b[33],c[33],d[33],e[33],t[33];
    itoa(a,t,2);
    for(int i=0;i<33;i++){
        if(t[i]=='\0'){
            tmp=i;
            break;
        }
    }
    for(int i=0;i<33;i++){
        b[i]='0';
    }
    for(int i=tmp;i>=0;i--){
        b[32-tmp+i]=t[i];
    }
    if(flag>=0){
        for(int i=0;i<33;i++){
            c[i]=b[i];
            d[i]=b[i];
            e[i]=b[i];
        }
        e[0]='1';
    }else{
        itoa(flag,d,2);
        b[0]='1';
        for(int i=1;i<32;i++){
            if(b[i]=='0'){
                c[i]='1';
            }else{
                c[i]='0';
            }
        }
        c[0]='1';c[32]='\0';
        for(int i=1;i<32;i++){
            e[i]=d[i];
        }
        e[0]='0';e[32]='\0';
    }
    printf("%s\n%s\n%s\n%s",b,c,d,e);
    return 0;
    
}

博弈论--矩形内画圆

上个月我在写acm的题时,碰到了这么一道题,直到昨天我才把它解出来。

题名:赢不了的谢强富

题目描述:

​ 某天,谢强富在慕课上看了两个人玩游戏,谢强富对这个游戏很感兴趣,所以他立马拉上了志强一起玩这个游戏。游戏规则如下:首先两个人在一张纸上画了一个长宽分别为A,B的严格的矩形,然后两人依次画半径为R的圆,两人画的圆可以相切但是绝对不允许相交,当其中某一个人无法画出圆的时候,他就输了。谢强富和志强都很聪明。谢强富要首先画圆,但是玩了很多次,谢强富发现自己输多赢少,他想请问你,什么时候他能赢。

Input

第一行输入n,代表有n组测试样例。

每一组测试样例输入矩形的长:A,宽:B,和圆的半径:R。

Output

对于每一组测试样例,如果谢强富能赢输出YES,否则输出NO。

Sample Input 1

2
4 5 6
5 5 2

Sample Output 1

NO
YES

解题思路:

​ 其实我刚开始拿到这道题时我也很懵,似乎对于每一个案例的解法都是不一样的,而圆的最优位置也无从得知,反正就是想方设法让对手画不下去。
​ 但片刻思考过后我们都应知道,第一个圆一定是画在矩形的正中心,这样其他空间的最大空白处就是除圆以外的矩形的四个角,而四个角能不能画下另一个圆似乎就要再次计算了,而且计算过程好像还挺复杂的,如果能画下,那别的三个角都能画下了,然后继续计算,角上的圆之间似乎又会产生空隙,我们继续计算最大的空隙是否能再画圆,而且这次的计算过程似乎还和上次不一样,也更复杂了。
这样就导致我们对于解题的整体思路不够清晰,写不出来代码。
​ 上述方法其实是个误区,我们应该这样想,假如A先画,如果能画下去,那么会有四个空位,四个空位如果不能继续画下去,那A就赢了,如果能画下去,那么画的顺序将是B,A,B,A,意思就是如果B能画,那么A也能画,然后还是B画,B又要在剩下的空间里画,如果B能画,由于空间是对称的,所以会有2N的空位画,这样A还是最后画,如此循环,发现最后B肯定会有画不下去的时候。
​ 所以我们得出结论只要先手的人能画下第一个圆,那么他就已经赢了。

源码:

#include<iostream>
using namespace std;
int main(){
    int n,a,b,r;
    cin>>n;
    while(n--){
        cin>>a>>b>>r;
        if(2*r<=a&&2*r<=b){
            cout<<"YES"<<endl;
        }else{
            cout<<"NO"<<endl;
        }
    }
    return 0;
}

心得:

莽做题,莽计算是会浪费很多时间的,找到规律,问题就迎刃而解了!

行政

关于BFS的例题

题名:银老板家的电梯

题目描述

众所周知银老板是喀兰贸易的老大,银老板家也很有钱,上下楼都要用电梯,但是电梯里面没有按钮,电梯外面有上和下,按上你就会上升mi层,按下你就会下降mi层,即到达i+mi层或者i-mi层,i是你的当前楼层。现在银老板在p层,他想要去t层,请你帮帮银老板他最少需要按多少下按钮可以到达目的地。说不定他就来到你岛了呢?如果你还没有理解题意的话好吧我就举个例子:比如银老板在第2层,想要去第5层,且m依次为4,1,2,3,4;则他最少需要按2次(连续按2次上或者先按1次下再按1次上)才能到达目的地。(楼层>=1)

输入
第一行一个n,p,t(1<=n,p,t<=200)

第二行n个整数m1,m2…….mn;(0<=mi<=50)

输出
一个整数表示从p层到t层最少需要按多少次。如果不能到达输出-1。

输入样例 1
5 2 5
4 1 2 3 4

输出样例 1
2

输入样例 2
6 3 2
1 2 3 4 5 6

输出样例 2
-1

解题思路

根据题意可知,每层楼对应的下一层选项最多有两个,所以我们采用二维数组来存储每一层的一些信息。再来采用BFS算法,在使用BFS算法时我们需要一个队列,对于已经入队的楼层,我们先检查它是否是我们要达到的楼层,若不是则出列,并且将它的下一层入队,是则直接输出该楼层的循环次数。

源码

第一种思路:这是正宗的BFS算法

#include<iostream>
#include<queue>
using namespace std;
struct floor{
    int pos;
    int count;
};
const int Max= 201;
queue<floor> q;
int a[Max];
bool b[Max];
int M[2]={1,-1};
int go(int s,int e,int n){
    floor now,next,first;
    first.count=0;
    first.pos=s;
    q.push(first);
    b[s]=true;
    while(!q.empty()){
        now=q.front();
        if(now.pos==e){
            return now.count;
        }
        for(int i=0;i<2;i++){
            int tmp=now.pos+M[i]*a[now.pos];
            if(b[tmp]!=true&&tmp>0&&tmp<=n){
                next.pos=tmp;
                next.count=now.count+1;
                q.push(next);
                b[tmp]=true;
            }
        }
        q.pop();
    }
    return -1;
}
int main(){
    int n,s,e;
    cin>>n>>s>>e;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }    
    cout<<go(s,e,n);
    return 0;
}

第二种思路:用递归投机取巧

#include<iostream>
#include<algorithm>
using namespace std;
const int N=220;
int num[N];
bool re[N];
int n,b=99999,a=0,p,t;
void go(int k,int a)
{
    if(a>b) return;
    if(!re[k+num[k]]&&k+num[k]<=n) {
        re[k+num[k]]=true;
        a++;
        go(k+num[k],a);
        a--;
        re[k+num[k]]=false;
    }
    if(!re[k-num[k]]&&k-num[k]>0) {
        re[k-num[k]]=true;
        a++;
        go(k-num[k],a);
        re[k-num[k]]=false;
        a--;        
    }
    if(k==t) b=a;
}
int main()
{
    cin>>n>>p>>t;
    for(int i=1;i<=n;i++)
    cin>>num[i];
    re[p]=true;
    go(p,0);
    if(b==99999)
       cout<<-1<<endl;
      else
       cout<<b<<endl;
}

这是正解。

My first blog

恍恍惚惚,现在都大二了,我开始意识到了对于学计算机的,写博客是多么的重要,于是就有了这个网站,希望能和大家一起学习。

  • Copyrights © 2021-2022 舒窈
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信