笔记

自定义函数递推的表达

对于:
1 2
2 8
3 26
... ...

8=2*3+2;

26=8*3+2...

除了第一行,其余行都是f(n-1)*3+2;

int f(int x){
    if(x==1)return 2;
    else{
        return f(x-1)*3+2;
    }
}

四舍五入的表达

printf("%.0f", len(sum)+0.1 );

printf("%.0f", len(sum)+0.000001 );

均可

侦探推理

题目描述

明明同学最近迷上了侦探漫画《柯南》并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏。游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明明的任务就是找出这个罪犯。接着,明明逐个询问每一个同学,被询问者可能会说: alt

证词中出现的其他话,都不列入逻辑推理的内容。

明明所知道的是,他的同学中有N个人始终说假话,其余的人始终说真。

现在,明明需要你帮助他从他同学的话中推断出谁是真正的凶手,请记住,凶手只有一个!

输入描述:

输入由若干行组成,第一行有二个整数,M(1≤M≤20)、N(1≤N≤M)和P(1≤P≤100);M是参加游戏的明明的同学数,N是其中始终说谎的人数,P是证言的总数。接下来M行,每行是明明的一个同学的名字(英文字母组成,没有主格,全部大写)。 往后有P行,每行开始是某个同学的名宇,紧跟着一个冒号和一个空格,后面是一句证词,符合前表中所列格式。证词每行不会超过250个字符。 输入中不会出现连续的两个空格,而且每行开头和结尾也没有空格。

输出描述:

如果你的程序能确定谁是罪犯,则输出他的名字;如果程序判断出不止一个人可能是罪犯,则输出 Cannot Determine;如果程序判断出没有人可能成为罪犯,则输出 Impossible。

输入

3 1 5

MIKE

CHARLES

KATE

MIKE: I am guilty.

MIKE: Today is Sunday.

CHARLES: MIKE is guilty.

KATE: I am guilty.

KATE: How are you??

输出

MIKE

using namespace std;
int m, n, p;
string name[30];
string s[110];
int a[30];  //a=1  说真话的人,a=2的时候是说假话的人 a=0还不知道是真是假
int cnt[4];  //cnt[1]是说真话的人数, cnt[2]是说假话的人数
int xiongshou[30];
string week[8] = {"","Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Satursday", "Sunday"};
int dijigeren(string s)  //s这个人的名字是谁的名字
{
    for (int i = 1; i <= m; i++)
        if (s == name[i]) return i;
    return 0;
}
int judge(int g, int d, string s)
//今天星期d,凶手是g的情况下s这句话是真话1还是假话2还是废话0
{
    int pos = s.find(":");//7
    if(s.find("I am guilty.") != string::npos) {
        if (name[g] == s.substr(0, pos)) return 1;
        else return 2;
    }
    if(s.find("I am not guilty.") != string::npos) {
         if (name[g] == s.substr(0, pos)) return 2;
         else return 1;
    }
    if(s.find(" is guilty.")!= string::npos){
        int t = s.find(" is guilty.");//13
        string tmpname = s.substr(pos+2, t-1 - (pos+2)+1);
        int num = dijigeren(tmpname);
        if (num == 0) return 0; //找不到这个人,说明说的是废话
        if (num == g) return 1;
        return 2;
    }

    if(s.find(" is not guilty.")!= string::npos){
        int t = s.find(" is not guilty.");
        string tmpname = s.substr(pos+2, t-1 - (pos+2)+1);
        int num = dijigeren(tmpname);
        if (num == 0) return 0;
        if (num == g) return 2;
        return 1;
    }

    if (s.find("Today is ")!= string::npos){
        int t = s.find("Today is ") + 9;  //找到的是T这个位置,但是现在要标记is后的空格这个位置
        string day = s.substr(t, s.length()-t-1);  //减去.这个位置
        int num = 0;
        for (int i = 1; i <= 7; i++)
            if (day == week[i]){
                num  = i; break;
                                }
        if (num == 0) return 0;//找不到是星期几,说的是废话
        if (num == d) return 1;
        return 2;
    }
    return 0;
}


int main()
{



    cin>>m>>n>>p;
    for (int i = 1; i <= m; i++)
        cin >> name[i]; // string s中s就相当于一个一维数组,所以name[i]相当于二维数组,
    //name[1]存储MIKE,name[2]存储CHARLES
//    cout <<name[1]<<endl;
//    cout<<judge(1, 1, "MIKE: Today is  day.")<<endl;
    getline(cin, s[0]);//把KATE后面的回车读走
    //在使用 cin 后若要使用 getline() 必须要把前面cin遗留的结束符处理掉,
    //解决方法为:在使用getline()之前,加入一行getline()来处理cin留下的结束符
    for (int i = 1; i <= p; i++)
        getline(cin, s[i]);
    for (int g = 1; g <= m; g++){  //凶手
    for (int d = 1; d <= 7; d++)  //星期几
    {
        memset(a, 0, sizeof(a));//对数组归零
        cnt[1]=cnt[2]=0;
        int flag = 1;
        for(int i = 1; i <= p; i++)
        {
            int tmp = judge(g, d, s[i]);
            int num = dijigeren(s[i].substr(0, s[i].find(":") ) );//如MIKE:就是从0到4
            //s[i].find(":")==4,表示从M开始读4个字符
           // printf("today=%d,i=%d,shuohuaderen=%d, zhengjia=%d\n", d,i,num,tmp);
            if(tmp != 0 && a[num] != 0 && tmp != a[num]) {
                flag = 0; break;  //若一个人说了真话但是判断他是说假话的人,
                //则说明之前给他的假设不成立即g=? d=?这个判断不成立,
                //可break掉把g或d换个数字来试,所以才有if(flag == 0) continue;
            }
            if(tmp != 0 && a[num] == 0) {
                a[num] = tmp;  cnt[tmp]++;//a[num]==0说明之前未知这个人是说真话还是假话
                //现在知道了,就把tmp赋给a[]
            }
        }
        
        if(flag == 0) continue;
        if (cnt[2] > n || cnt[2]+(m-cnt[1]-cnt[2]) < n) break;//说假话的人数>n
        //或假设说废话的人全是说假话的,再加上确认是说假话的还<n 则不满足题意
        xiongshou[g] = 1;//把可疑的凶手都标记起来
    }
                                }
    
    int cnt = 0, pos = 0;
    for(int i = 1; i <= m; i++)
    {
        if (xiongshou[i] == 1) cnt++,pos=i;
    }
    if (cnt == 0) cout<<"Impossible";
    if (cnt == 1) cout<<name[pos];
    if (cnt > 1 ) cout<<"Cannot Determine";
    return  0;
}

高精度的表达

两数相加

如:

514

495

1009


#include<bits/stdc++.h>
using namespace std;
int main(){
	string s,s1;
	cin>>s>>s1;
	int a[1000],b[1000],c[1000]={0} ;
	int lena=s.length(),lenb=s1.length() ;
    int len=max(lena,lenb);
    for(int i=lena-1,j=1;i>=0;i--,j++){//字符串是从s[0]开始
      a[j]=s[i]-'0';
								}
	for(int i=lenb-1,j=1;i>=0;i--,j++){//字符串是从s[0]开始 
      b[j]=s1[i]-'0';
								}
	for(int i=1;i<=len;i++){  //从个位开始加
		c[i]=c[i]+a[i]+b[i];//c[i]从1开始后面不会混乱 ,可能前一位给了后一位某个数值所以要加c[i] 
			c[i+1]=c[i]/10;
		    c[i]=c[i]%10;
		
	}
	if(c[len+1]) //最后一位会不会进位
	len++;
	for(int i=len;i>=1;i--){
		printf("%d",c[i] );
	}							
	
	return 0;
	
}

两数相减

#include<bits/stdc++.h>
using namespace std;
int t,a[1000],b[1000];
void trans(string s,int a[] ){
    for(int i=1,j=s.length()-1;j>=0;j--,i++){
        a[i]=s[j]-'0';
    }
}
    
bool judge(string s,string s1){  //判断两个数谁大谁小 
	int lena=s.length(), lenb=s1.length() ;
	if(lena>lenb) return 1;//比较数位长度 
	if(lena<lenb) return 0;
	if(s>=s1) return 1;//数位相同时从高位开始比较字典序 
	return 0;
}

void jian(int a[],int b[],int lena,int lenb ){
	int c[1000]={0};
	int len=max(lena,lenb);
	for(int i=1;i<=len;i++){
		c[i]=c[i]+a[i]-b[i];
		if(c[i]<0){
			c[i]=c[i]+10;
			c[i+1]--;
		} 
	}
	while(c[len]==0)//防止出现类似001
	len--;
	for(int i=len;i>=1;i--)
	printf("%d",c[i] );
} 
int main(){
    string s,s1;
    cin>>s>>s1;//用字符串输入可直接知道长度(位数)
    int lena=s.length(), lenb=s1.length() ;
    trans(s,a);//把字符串转换成数组
    trans(s1,b);//数组传递的是首地址,形参改变实参也改变了
    if(judge(s,s1))  
	jian(a,b,lena,lenb);
    else{
    	printf("-");jian(b,a,lena,lenb);//如1-799 统一变成大数减小数,再添个负号 
	}
    return 0;
}

两数相乘

#include<bits/stdc++.h>
using namespace std;
int t,a[1000],b[1000];
void trans(string s,int a[] ){
    for(int i=1,j=s.length()-1;j>=0;j--,i++){
        a[i]=s[j]-'0';
    }
}
    
void cheng(int a[],int b[] ,int lena, int lenb){
    int  c[1000]={0},len=lena+lenb ;//三位数乘三位数最多是六位数(999*999),一般是三位数
    for(int i =1;i<=lena;i++){  //a[1]*b[1]是结果的第i+j-1位
        for(int j=1;j<=lenb;j++){
            c[i+j-1]+=a[i]*b[j];//要加上它本身,因为后面的进位可能已经给该位赋值了
        }
    }
    for(int i=1;i<=len;i++){
        c[i+1]+=c[i]/10;//处理进位
        c[i]=c[i]%10;
    }
    if(c[len]==0)len--;//结果可能只是五位数(若是三位数相乘)
        for(int k=len;k>=1;k--)
            printf("%d",c[k] );
}

int main(){
    string s,s1;
    cin>>s>>s1;//用字符串输入可直接知道长度(位数)
    int lena=s.length(), lenb=s1.length() ;
    trans(s,a);//把字符串转换成数组
    trans(s1,b);//数组传递的是首地址,形参改变实参也改变了
    cheng(a,b,lena,lenb);
    return 0;
}

两数相除

1、高精度÷低精度(int)

#include<bits/stdc++.h>
using namespace std;
int t,a[1000],b[1000];

void chu(string s,int b ){
	int c[1000]={0};
	int len=s.length();   //被除数有几位就要进行几次运算
	int rest=0;
	for(int i=0;i<len;i++){   //string是从s[0]开始读入 
		rest = rest*10+s[i]-'0';
		c[i]=rest/b;
		rest=rest%b;
	}
	int pos=0;
	while(c[pos]==0)
	pos++;
	for(int i=pos;i<len;i++)
	printf("%d",c[i] );
	printf("\n%d",rest);//输出余数 
} 
int main(){
    string s;
    int b;
    cin>>s>>b;//用字符串输入可直接知道长度(位数)
    chu(s,b);  //默认a>b 
    return 0;
}

全部评论

相关推荐

1 收藏 评论
分享
牛客网
牛客企业服务