zoukankan      html  css  js  c++  java
  • 数据结构实验1-2——2020

    问题 A: 判断三角形形状

    题目描述

    给你三角形的三条边,你能告诉我它是哪种三角形吗?
    如果是直角三角形,请输出“good”。如果是等腰三角形,请输出“perfect”。否则,请输出“just a triangle”。
    题目保证输入数据合法。

    输入

    输入的第一行为一个整数t,表示测试样例的数量。
    每组样例包含了三个整数a,b,c,代表了三角形的三条边的长度。(0<a,b,c<300)

    输出

    对于每组样例,输出结果,每组结果占一行。

    样例输入

    4
    3 4 5
    2 2 3 
    1 4 4
    4 6 3
    

    样例输出

    good
    perfect
    perfect
    just a triangle
    

    代码

    #include<iostream>
    #include<algorithm>
    using namespace std;
    int triangle()
    {
        int a[3];
    	for(int i=0;i<3;i++)
    	cin>>a[i];
    	sort(a,a+3);
    	if(a[0]+a[1]>a[2])
    	{
    		if(a[0]*a[0]+a[1]*a[1]==a[2]*a[2])
    		cout<<"good"<<endl;
    		else if(a[0]==a[1]||a[1]==a[2])
    		cout<<"perfect"<<endl;
    		else cout<<"just a triangle"<<endl;
    	}
    }
    int main()
    {     
          int n;
          cin>>n;
          for(int j=0;j<n;j++)
          triangle();
    	  return 0;
    }
    

    问题 B: 笨鸟先飞

    题目描述

    多多是一只小菜鸟,都说笨鸟先飞,多多也想来个菜鸟先飞。于是它从0点出发,一开始的飞行速度为1m/s,每过一个单位时间多多的飞行速度比上一个单位时间的飞行速度快2m/s,问n(0<n<10^5)个单位时间之后多多飞了多远?

    输入

    先输入一个整数T表示有几组数据。每组数据输入一个n,表示多多飞行的时间。

    输出

    输出多多飞行了多远,因为数字很大,所以对10000取模。

    样例输入

    2
    1
    2
    

    样例输出

    1
    4
    

    貌似就平方?

    代码

    #include<iostream>
    using namespace std;
    int prefly(int n)
    {
    	int sum=0;
    	int p=1;
    	for(int i=0;i<n;i++)
    	{
    		sum=(sum+p)%10000;
    		p+=2;	
    	}
    	return sum;	
    }
    int main()
    {
    	int t;
    	cin>>t;
    	int n;
    	for(int j=0;j<t;j++)
    	{
    	cin>>n;
    	cout<<prefly(n)<<endl;
        }
    }
    

    问题 C: 火车出站

    题目描述

    铁路进行列车调度时,常把站台设计成栈式结构的站台,试问:
    设有编号为1到n的n辆列车,顺序开入栈式结构的站台,则可能的出栈序列有多少种?

    输入

    输入包含多组测试数据。每组为一个正整数n(1<=n<=20),表示有n辆列车。

    输出

    输出可能的出栈序列有多少种。

    样例输入

    4
    3
    

    样例输出

    14
    5
    

    参考:卡特兰数

    可知满足递推式:h(n)=h(n-1)*(4*n-2)/(n+1);

    代码

    #include<iostream>
    using namespace std;
    long long out(long n)
    { if(n==1)
      return 1;
      else
      return out(n-1)*(4*n-2)/(n+1); 	
    }
    int main()
    {
    	long long t;
    	while(cin>>t)
    	cout<<out(t)<<endl;	
    }
    

    问题 D: 最少的交换

    题目描述

    现在给你一个由n个互不相同的整数组成的序列,现在要求你任意交换相邻的两个数字,使序列成为升序序列,请问最少的交换次数是多少?

    输入

    输入包含多组测试数据。每组输入第一行是一个正整数n(n<500000),表示序列的长度,当n=0时。
    接下来的n行,每行一个整数a[i](0<=a[i]<=999999999),表示序列中第i个元素。

    输出

    对于每组输入,输出使得所给序列升序的最少交换次数。

    样例输入

    5
    9
    1
    0
    5
    4
    3
    1
    2
    3
    0
    

    样例输出

    6
    0
    

    什么是归并排序?

    代码

    #include <iostream>
    using namespace std;
    const int maxn = 500010;
    int a[maxn];
    int aux[maxn];
    long long sum;
    int n;
    
    void merge(int l, int mid, int r) //归并排序
    {
        int i = l;//第一部分的排好序的 
        int end1 = mid;
        int j = mid+1;//第二部分的排好序的 
        int end2 = r;
    
        for (int t = l; t <= r; t++) 
            aux[t] = a[t];//将初始的数组a[]全部录入到aux[]中 
        for (int t = l; t <= r; t++)//从左往右遍历数组a[] 
        {
            if (j > end2)//第二部分排好序的遍历完成,直接记录剩余的第一部分排好序的,移动次数不增加 
                a[t] = aux[i++];
            else if (i > end1)//第一部分排好序的遍历完成,直接记录剩余的第二部分排好序的,移动次数不增加  
                a[t] = aux[j++];
            else if (aux[i] > aux[j])//第一部分排好序的第一个元素>第二部分排好序的第一个元素 
            {
                sum += mid+1-i;//移动的元素为a[j]到a[i](即aux[i])的位置,次数为j-i(即mid+1-i) 
                a[t] = aux[j++];
            } 
            else if (aux[i] <= aux[j])//第一部分排好序的第一个元素<=第二部分排好序的第一个元素 
                a[t] = aux[i++];//记录到a[]中,i++,变为第一部分排好序的第二个元素 
        }
    }
    
    void msort(int l, int r) 
    {
        if (l < r) 
        {
            int mid = (l + r)  / 2;
            msort(l, mid);
            msort(mid+1, r);
            merge(l, mid, r);
        }
    }
    
    int main(void) 
    {
        while (cin >> n && n) 
        {
            sum = 0;
            for (int i = 0; i < n; i++) 
                cin >> a[i];
            msort(0, n-1);
            cout << sum << endl;
        }
        return 0;
    }
    
    //本地能运行,为啥oj上老是段错误?TAT
    #include<iostream> 
    using namespace std;
    int bubble(int a[],int time,int length)//返回交换次数 
    {             	
    	int p; 
    	for(int j=0;j<length-1;j++)
    	  for(int i=0;i<length-1-j;i++)
    	   if(a[i]>a[i+1])
    	   {
    	   	 p=a[i];
    	   	 a[i]=a[i+1];
    	   	 a[i+1]=p;
    	   	 time++;
    	   } 
    	return time;
    }
    int main()
    {
    	int time=0;  //time记录交换次数 
    	int length=0;//length记录输入元素个数 
    	int n;
    	int a[5000];
    	while(cin>>n&&n!=0)
    	{
    		length=n;
    		for(int i=0;i<n;i++)
    		cin>>a[i];
    		cout<<bubble(a,time,length)<<endl;
    		time=0;
    		length=0;
    	}
    	return 0;	
    }
    
    

    问题 E: 欧几里得游戏

    题目描述

    小明和小红在玩欧几里得游戏。他们从两个自然数开始,第一个玩家小明,从两个数的较大数中减去较小数的尽可能大的正整数倍,只要差为非负即可。然后,第二个玩家小红,对得到的两个数进行同样的操作,然后又是小明。就这样轮流进行游戏,直至某个玩家将较大数减去较小数的某个倍数之后差为0为止,此时游戏结束,该玩家就是胜利者。

    输入

    输入包含多组测试数据。每组输入两个正整数,表示游戏一开始的两个数,游戏总是小明先开始。
    当输入两个0的时候,输入结束。

    输出

    对于每组输入,输出最后的胜者,我们认为他们两个都是顶尖高手,每一步游戏都做出了最佳的选择。
    具体输出格式见输出样例。

    样例输入

    34 12
    15 24
    0 0
    

    样例输出

    xiaoming wins
    xiaohong wins
    

    算法参考

    代码

    #include<iostream>
    using namespace std;
    int main()
    {
        int a,b,k,t;
        while(cin>>a>>b,a!=0||b!=0)
        {
            k=1;
            if(a==b)
                cout<<"xiaoming wins"<<endl;    
            else
            {
                while(a!=b)
                {
                    if(a<b)//如果a<b,就交换ab值
                    {
                        t=a;
                        a=b;
                        b=t;
                    }
                    k++;
                    if(a/b!=1)
                    {
                        break;
                    }
                    a=a%b;
                }
                if(k%2==1)
                    cout<<"xiaohong wins"<<endl;
                else
                    cout<<"xiaoming wins"<<endl;
            }
        }
        return 0;
    }
    

    问题 F: 取石子游戏

    题目描述

    一天小明和小红在玩取石子游戏,游戏规则是这样的:
    (1)本游戏是一个二人游戏;
    (2)有一堆石子,共有n个;
    (3)两人轮流进行;
    (4)每走一步可以取走1~m个石子;
    (5)最先取光石子的一方为胜。
    如果游戏的双方使用的都是最优策略,请输出哪个人能赢。

    输入

    输入的第一行是一个正整数C(C<=100),表示有C组测试数据。
    每组输入两个整数n和m(1<=n,m<=1000),n和m的含义见题目描述。

    输出

    对于每组输入,如果先走的人能赢,请输出“first”,否则请输出“second”。

    样例输入

    2
    23 2
    4 3
    

    样例输出

    first
    second
    

    算法参考

    代码

    #include<iostream>
    using namespace std;
    int getstone(int n,int m)
    {
    	if(n%(m+1)==0) return 0;
    	else return 1;	
    }
    int main()
    {
    	int c;
    	cin>>c;
    	int n,m;
    	for(int i=0;i<c;i++)
    	{
    		cin>>n>>m;
    		if(getstone(n,m))
    		cout<<"first"<<endl;
    		else
    		cout<<"second"<<endl;	
    	}
    	
    }
    
    

    问题 G: 奥运排序问题

    题目描述

    按要求,给国家进行排名。

    输入

    有多组数据。
    第一行给出国家数N,要求排名的国家数M,国家号从0到N-1。
    第二行开始的N行给定国家或地区的奥运金牌数,奖牌数,人口数(百万)。
    接下来一行给出M个国家号。

    输出

    排序有4种方式: 金牌总数 奖牌总数 金牌人口比例 奖牌人口比例
    对每个国家给出最佳排名排名方式 和 最终排名
    格式为: 排名:排名方式
    如果有相同的最终排名,则输出排名方式最小的那种排名,对于排名方式,金牌总数 < 奖牌总数 < 金牌人口比例 < 奖牌人口比例
    如果有并列排名的情况,即如果出现金牌总数为 100,90,90,80.则排名为1,2,2,4.
    每组数据后加一个空行。

    样例输入

    4 4
    4 8 1
    6 6 2
    4 8 2
    2 12 4
    0 1 2 3
    4 2
    8 10 1
    8 11 2
    8 12 3
    8 13 4
    0 3
    

    样例输出

    1:3
    1:1
    2:1
    1:2
    
    1:1
    1:1
    

    提示

    本题需要解决的是奥运会中各国家最有利的排名方式以及名次。只要进行五次排序即可。首先读入各国家信息,写好国家编号,计算和存储排名所需要的数据。然后按四种排名方式分别对需要排名的国家进行排名,并记录名次。最后使用国家编号对国家进行排名。这样就可以输出结果了。

    第n次无耻地copy学长的代码 。

    代码

    #include<iostream>
    using namespace std;
    struct nation
    {
    	int gold,medal;
    	double pop,gpp,mpp;
    	int rank1,rank2,rank3,rank4,highrank;
    	int rankmethod;
    };
    int main()
    {
    	int n,m;
    	while(cin>>n>>m)
    	{
    	int b[m];
    	int x,y;
    	double z;
    	nation na[n];
    	for(int i=0;i<n;i++)
    	{
    	 cin>>x>>y>>z;
    	 na[i].gold=x;
    	 na[i].medal=y;
    	 na[i].pop=z;
    	 na[i].gpp=x/z;
    	 na[i].mpp=y/z;
        }
        
        for (int j=0;j<m;j++)
        cin>>b[j];
        
        
        
        for(int i=0;i<n;i++)
        {
    	    na[i].rank1=na[i].rank2=na[i].rank3=na[i].rank4=1; 
            for(int j=0;j<n;j++)
            {   
                if(na[i].gold<na[j].gold)//gold排名 
                na[i].rank1++;
            }
        } 
         for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(na[i].medal<na[j].medal)//medal排名 
                na[i].rank2++;
            }
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(na[i].gpp<na[j].gpp)//gpp排名 
                na[i].rank3++;
            }
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(na[i].mpp<na[j].mpp)//mpp排名 
                na[i].rank4++;
            }
        }
        for(int i=0;i<n;i++)
        {
            na[i].highrank=na[i].rank1;
            na[i].rankmethod=1;
            if(na[i].highrank>na[i].rank2)
            {
                na[i].highrank=na[i].rank2;
                na[i].rankmethod=2;
            }
            if(na[i].highrank>na[i].rank3)
            {
                na[i].highrank=na[i].rank3;
                na[i].rankmethod=3;
            }
            if(na[i].highrank>na[i].rank4)
            {
                na[i].highrank=na[i].rank4;
                na[i].rankmethod=4;
            }
        }
        
        for(int i=0;i<m;i++)//取出b数组里需要排序的国家的序号,即b[i] 
        {
            cout<<na[b[i]].highrank<<':'<<na[b[i]].rankmethod<<endl;
        }
        cout<<endl;
    }
    }
    

    问题 H: 字符串的查找删除

    题目描述

    给定一个短字符串(不含空格),再给定若干字符串,在这些字符串中删除所含有的短字符串。

    输入

    输入只有1组数据。
    输入一个短字符串(不含空格),再输入若干字符串直到文件结束为止。

    输出

    删除输入的短字符串(不区分大小写)并去掉空格,输出。

    样例输入

    in
    #include 
    int main()
    {
    
    printf(" Hi ");
    }
    

    样例输出

    #clude
    tma()
    {
    
    prtf("Hi");
    }
    

    提示

    注:将字符串中的In、IN、iN、in删除。

    字符串这块儿学的不太好

    代码

    #include <string>
    #include <iostream>
    using namespace std;
    int main()
    {
        string a,str;
        getline(cin,a); //输入短字符串
        for(int i = 0; i<a.size(); ++i)
        { //将a中字符串全部改为小写字母
            a[i] = tolower(a[i]);
        }
        while(getline(cin,str))
        {
            string b = str,c = b; //将字符串保存至b,c,b将用于保存小写化后的字符,c保存原字符串
            for(int i = 0; i<b.size(); ++i)
            { //将b中的字符全部改为小写,便于匹配
                b[i] = tolower(b[i]);
            }
            int t = b.find(a,0); //在b串中查找a的位置,返回索引
            while(t != string::npos) //查找成功,则重复循环
            {
                c.erase(t,a.size());
                b.erase(t,a.size());
                t = b.find(a,t); //从t位置为起点继续查找b中下一个出现字符串a的位置
            }
            t = c.find(' ',0);
            while(t != string::npos)
            { //删除c中所有空格
                c.erase(t,1);
                t = c.find(' ',0);
            }
            cout<<c<<endl;
        }
        return 0;
    }
    

    问题 I: 后缀子串排序

    题目描述

    对于一个字符串,将其后缀子串进行排序,例如grain
    其子串有:
    grain
    rain
    ain
    in
    n
    然后对各子串按字典顺序排序,即:
    ain,grain,in,n,rain

    输入

    每个案例为一行字符串。

    输出

    将子串排序输出

    样例输入

    grain
    banana
    

    样例输出

    ain
    grain
    in
    n
    rain
    a
    ana
    anana
    banana
    na
    nana
    

    有空要补补这方面的知识

    代码

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    bool cmp(string s1,string s2)//--以升序形式排列 
    {
         return  s1 < s2;                  
    }
    int main ()
    {
        int i,j;
        char in[1000];//输入单词 
        string out[1000];//输出的数组,每个元素记录一个去掉一个字母的单词,未排序 
        //eg:输入grain,out[0]=grain,out[1]=rain 
        while(cin>>in)
        { 
            int len=strlen(in);//计算in这个数组实际有字符的长度 
            for(i=0;i<len;i++)
            {
                string c="";//重新设一个string类型的变量来记录每个out[i]值 
                for(j=i;j<len;j++)
                    c+=in[j];
                out[i]=c;   
            }   
            sort(out,out+len,cmp);//out+len不是out+1000 
            for(i=0;i<len;i++)
                cout<<out[i]<<endl;
        }
        return 0; 
    }
    

    问题 J: 算法:快速排序

    题目描述

    快速排序是对起泡排序的一种改进。它的基本思想是,通过一趟排序将待排序的记录分割成两个独立的部分,其中一部分记录的关键字均比另一部分的关键字小,在分成两个部分之后则可以分别对这两个部分继续进行排序,从而使整个序列有序。

    快速排序的算法可以描述如下:

    在本题中,读入一串整数,将其使用以上描述的快速排序的方法从小到大排序,并输出。

    输入

    输入的第一行包含1个正整数n,表示共有n个整数需要参与排序。其中n不超过100000。

    第二行包含n个用空格隔开的正整数,表示n个需要排序的整数。

    输出

    只有1行,包含n个整数,表示从小到大排序完毕的所有整数。

    请在每个整数后输出一个空格,并请注意行尾输出换行。

    样例输入

    10
    2 8 4 6 1 10 7 3 5 9
    

    样例输出

    1 2 3 4 5 6 7 8 9 10 
    

    提示

    在本题中,需要按照题目描述中的算法完成快速排序的算法。

    快速排序是一种十分常用的排序算法,其平均时间复杂度为O(knlnn),其中n为待排序序列中记录的个数,k为常数。大量的实际应用证明,在所有同数量级的此类排序算法中,快速排序的常数因子k是最小的,因此,就平均时间而言,快速排序是目前被认为最好的一种内部排序方法。

    而在C语言的常用编译器中,qsort函数是一个非常常用的快速排序函数。

    库函数直接搞定了,哈啊哈。

    代码

    //偷懒版
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int main() 
    {
    	int n;
    	cin>>n;
    	int a[n];
    	for(int i=0;i<n;i++)
    	cin>>a[i];
    	sort(a,a+n);
    	for(int i=0;i<n;i++)
    	cout<<a[i]<<' ';
    	cout<<endl;	
    }
    
    //另一
    #include <iostream>
    using namespace std;
    void Qsort(int arr[], int low, int high)
    {
        if (high <= low) return;
        int i = low;
        int j = high + 1;
        int key = arr[low];
        while (true)
        {
            /*从左向右找比key大的值*/
            while (arr[++i] < key)
            {
                if (i == high){
                    break;
                }
            }
            /*从右向左找比key小的值*/
            while (arr[--j] > key)
            {
                if (j == low){
                    break;
                }
            }
            if (i >= j) break;
            /*交换i,j对应的值*/
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
        /*中枢值与j对应值交换*/
        int temp = arr[low];
        arr[low] = arr[j];
        arr[j] = temp;
        Qsort(arr, low, j - 1);
        Qsort(arr, j + 1, high);
    }
    int main()
    {
        int num;
        cin>>num;
        int a[num];
        for(int i=0;i<num;i++)cin>>a[i];
        Qsort(a,0,num-1);/*这里原文第三个参数要减1否则内存越界*/
        for(int i=0;i<num;i++)cout<<a[i]<<' ';
        return 0;
    }
    

    问题 K: 为什么1024是程序员节

    题目描述

    小雏鸟正在看剧。突然被插播的广告吓了一跳。

    只见广告上说 1024你懂的

    小雏鸟不懂, 问身边的大白。大白说,这个1024是2的10次方,程序员把10月24日作为程序猿日。

    现在给你一个整数N,让你求2的N次方有多大。

    输入

    一个整数N,N<30

    输出

    一个整数,2的N次方的结果

    样例输入

    10
    

    样例输出

    1024
    

    pow函数不给过?

    代码

    #include<iostream>
    using namespace std;
    int main()
    {
    	int n;
    	int sum=1;
    	cin>>n;
    	for(int i=0;i<n;i++)
    	sum*=2;
    	cout<<sum;
    }
    
  • 相关阅读:
    [OpenWRT]判断WDS是否开启
    【cocos2d-js官方文档】一、搭建 Cocos2d-JS 开发环境
    noi Big String 超级字符串
    序列 xulie (2017青岛)
    %%%城市交通费 city //程序超时
    3.密码pasuwado————记第一次超越Candy?
    图论-欧拉回路(邻接链表)
    blue and red ball
    魔方→︿←
    The first DP!
  • 原文地址:https://www.cnblogs.com/gylic/p/13042870.html
Copyright © 2011-2022 走看看