RPG的错排
此博客链接:https://www.cnblogs.com/ping2yingshi/p/12491394.html
RPG的错排(77min)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2068
需要用到错排公式以及高中数学排列组合的知识。
排列组合: 【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; } }