RPG的错排

此博客链接:https://www.cnblogs.com/ping2yingshi/p/12491394.html

RPG的错排(77min)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2068

Problem Description
今年暑假杭电ACM集训队第一次组成女生队,其中有一队叫RPG,但做为集训队成员之一的野骆驼竟然不知道RPG三个人具体是谁谁。RPG给他机会让他猜猜,第一次猜:R是公主,P是草儿,G是月野兔;第二次猜:R是草儿,P是月野兔,G是公主;第三次猜:R是草儿,P是公主,G是月野兔;......可怜的野骆驼第六次终于把RPG分清楚了。由于RPG的带动,做ACM的女生越来越多,我们的野骆驼想都知道她们,可现在有N多人,他要猜的次数可就多了,为了不为难野骆驼,女生们只要求他答对一半或以上就算过关,请问有多少组答案能使他顺利过关。
 
Input
输入的数据里有多个case,每个case包括一个n,代表有几个女生,(n<=25), n = 0输入结束。
 
Sample Input
1
2
0
 
Sample Output
1
1
题解:
         题意:知道n个人的名字,但是不知道谁对应谁,猜n个人的名字,猜对一半以上就算过关。
         方法:组合和错排。
         知识补充:           

                          需要用到错排公式以及高中数学排列组合的知识。

                          排列组合:    【1】排列(从n中拿出m个,并进行排列):     A_n_m=n!/(n-m)!=n*(n-1)*(n-2)*........(n-m+1);

                                             【2】组合(从n中拿出m个,不进行排列):     C_n_m=n!/((n-m)!*m!)=n*(n-1)*(n-2)*........(n-m+1)/(m*(m-1)*.......1);

         思路:

                  本题要求答对一半或以上人数,所以只需要求出小于一半的人数错排的可能的总和, 因为是从n个人里选出m个排错的人,因此需要对m排错的人(m<=n/2)进行组合,再乘以对应的排错人数最后在累加。

        注意:最后结果可能超过int 范围。

组合代码:

public static long  C_n_m(int n,int m){
        long sum1=1;
        long sum2=1;
        for(int i=n-m+1;i<=n;i++)
        {
            sum1=sum1*i;
        }
        for(int i=1;i<=m;i++)
        {
            sum2=sum2*i;
        }
        return sum1/sum2;
        
    }

错排代码:

            long []arr=new long[26];
            arr[0]=0;
            arr[1]=0;
            arr[2]=1;
            for(int i=3;i<=25;i++)
             {
                   arr[i]=(i-1)*(arr[i-1]+arr[i-2]);
             }

代码如下:

import java.util.Scanner;


public class test {
    public static long  C_n_m(int n,int m){
        long sum1=1;
        long sum2=1;
        for(int i=n-m+1;i<=n;i++)
        {
            sum1=sum1*i;
        }
        for(int i=1;i<=m;i++)
        {
            sum2=sum2*i;
        }
        return sum1/sum2;
        
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
       Scanner scan=new Scanner(System.in);
        
          
            long []arr=new long[26];
            arr[0]=0;
            arr[1]=0;
            arr[2]=1;
            for(int i=3;i<=25;i++)
             {
                   arr[i]=(i-1)*(arr[i-1]+arr[i-2]);
             }
            while(scan.hasNext())
            {
                  long result=1;
                  int n=scan.nextInt();
                  if(n==0)
                  {
                      break;
                  }
                
                  for(int i=1;i<=n/2;i++) 
                      result+=arr[i]*C_n_m(n,i);
                 
                  System.out.println(result);
               
            }

      }
    

}

合并两个有序链表 (62min)

题目链接:https://leetcode-cn.com/problems/merge-two-sorted-lists/

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

题解:

          题意:两个链表合并成一个有序链表(按照从小到大升序)。

          方法:有链接的头插法把两个链表合并成一个链表。

          思路:新生成一个头结点和头指针,然后取两个链表中较小的值赋值给头指针,较小的指针向后移动,头指针也向后移动,直到所有值都插入新的链表中。

          我是看数据结构书这么写的额,然后看别人题解优化了一下,可是代码报错,我没有找到错误在哪里。

代码如下:

struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
     ListNode head;
     ListNode *tail=&head;
        while(l1 || l2){
            if(!l2 || l1 && l1->val <= l2->val){
                tail->next=l1,l1=l1->next;
            }else{
                tail->next=l2,l2=l2->next;
            }
            tail=tail->next;
        }
       

}
原文地址:https://www.cnblogs.com/ping2yingshi/p/12491394.html