Insertion Sort——打表找规律

【题目描述】

Insertion sort is a simple sorting algorithm that builds the final sorted array one item at an iteration.More precisely, insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. It repeats until no input elements remain.This type of sorting is typically done in-place, by iterating up the array, growing the sorted array behind it. At each array-position, it checks the value there against the largest value in the sorted array (which happens to be next to it, in the previous array-position checked). If larger, it leaves the element in place and moves to the next. If smaller, it finds the correct position within the sorted array, shifts all the larger values up to make a space, and inserts into that correct position.The resulting array after k iterations has the property where the first k entries are sorted. In each iteration the first remaining entry of the input is removed, and inserted into the result at the correct position, thus extending the result.Knuth is an ACM-ICPC master and provides a modified pseudocode implementation about the insertion sort for you. His modified algorithm for an array of sortable items A (1-based array) can be expressed as:He notes that a permutation of 1 to n is almost sorted if the length of its longest increasing subsequence is at least (n−1).Given the parameter k, you are asked to count the number of distinct permutations of 1 to n meeting the condition that, after his modified insertion sort, each permutation would become an almost sorted permutation.Input
The input contains several test cases, and the first line contains a positive integer T indicating the number of test cases which is up to 5000.For each test case, the only line contains three integers n,k and q indicating the length of the permutations, the parameter in his implementation and a prime number required for the output respectively, where 1≤n,k≤50 and 108≤q≤109.Output
For each test case, output a line containing "Case #x: y" (without quotes), where x is the test case number starting from 1, and y is the remainder of the number of permutations which meet the requirement divided by q.Example
Input
4
4 1 998244353
4 2 998244353
4 3 998244353
4 4 998244353
Output
Case #1: 10
Case #2: 14
Case #3: 24
Case #4: 24
Note
In the first sample case, we can discover 10 permutations which meet the condition, and they are listed as follows:[1,2,3,4];
[1,2,4,3];
[1,3,2,4];
[1,3,4,2];
[1,4,2,3];
[2,1,3,4];
[2,3,1,4];
[2,3,4,1];
[3,1,2,4];
[4,1,2,3].

【题目分析】

这是一道打表题。自己以前对这种题很没有经验,因为不太习惯这种思维方式,虽然清楚找出来的规律肯定是有其深层含义的,但是直接找这种规律是很困难的,而且对于竞赛而言也并不需要理解公式的来源,能够解决问题就行,当然探求问题本质的习惯很好,但是对于竞赛我们很多时候要不求甚解,大胆尝试不去求证。不管黑猫白猫,能够抓到老鼠就是好猫,可能在思维层次上两个有优劣,但是从解决问题的角度都是一样的,不能因为觉得这样没水平或者是没有找到问题的本质就对这种有效解决问题的方式抵触。只能怪自己的思维不允许自己一下看出问题的关键而只能通过这种方式帮助解决问题。

而且快速找到规律也是一种能力,不能过分纠结于细节,这是为了找到规律而不是为了探求为什么。

【AC代码】

打表代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<climits>
#include<cctype>
#include<queue>
#include<set>using namespace std;typedef long long ll;
const int INF=0x3f3f3f3f;
const int MAXN=30;int nn,k;
int a[MAXN];
int b[MAXN];
int dp[MAXN];int deal(int n)
{for(int i=1;i<=n;i++){dp[i]=1;}int ret=0;for(int i=1;i<=n;i++){for(int j=1;j<i;j++){if(b[j]<b[i] && dp[j]+1>dp[i]) dp[i]=dp[j]+1; }if(dp[i]>ret) ret=dp[i];}return ret;
}int main()
{nn=10;for(int n=1;n<=nn;n++){printf("[%d]\t",n);for(int i=1;i<=n;i++) a[i]=i;for(int k=1;k<=n;k++){int cnt=0;do{memcpy(b,a,sizeof(a));sort(b+1,b+1+k);if(deal(n)>=n-1) cnt++;}while(next_permutation(a+1,a+n+1));printf("%d\t",cnt);}printf("\n");}return 0;
}

AC代码

#include<stdio.h>
int main()
{long long t,n,k,q,cot=0;scanf("%lld",&t);while(cot!=t){cot++;scanf("%lld%lld%lld",&n,&k,&q);if(k>n)k=n;long long ans=0,temp=1;for(long long i=1;i<=k;i++){temp*=i;temp%=q;}ans=temp;long long tz=k;for(long long i=k+1;i<=n;i++){ans+=temp*k;ans%=q;k+=2;}printf("Case #%lld: %lld\n",cot,ans);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/383989.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据链路层: 可靠性传输 六个协议

可靠性传输 1. 差错控制 发送方将数据帧发送, 但是当发送方发送的是一个 1的时候此时接受方却接受的是一个 0. (1)校验 接收方如果帧校验接受到的帧没有问题, 则对发送方发送一个肯定性的确认, 当对这个数据帧进行校验发现这个帧有问题的时候, 此时接受方一种是将这个数据帧…

c语言实现配置文件的读写

配置文件的格式如下&#xff1a; key1 value1 key2 value2 . . . 名值对以一个链接&#xff0c;一条记录以换行符分割 头文件&#xff1a; #include<stdio.h> #include<stdlib.h> #include <string.h> 函数原型&#xff1a; void trim(char *strIn, char *…

Educational Codeforces Round 73 (Rated for Div. 2)

A 很简单的一个模拟&#xff0c;只要前面的数字有两个以上就能合成后面的&#xff0c;我们进行一遍合成看能不能出现2048就可以了。 #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include&…

数据链路层: HDLC

一. 协议机 发送方和接收方. 同时有限状态机把协议形式化为一个四元组 (S,M,I,T), 其中你S表示进程和信道可能进入的集合, M 表示数据帧的状态, I 表示进程的初始状态, T 表示两两状态之间的转化. 每个系统状态可以分为发送状态, 接受状态和信道状态. 把状态用一个点进行表示,…

Miller_Rabin算法

为了测试一个大整数是不是素数&#xff0c;我们不能够使用传统的测试是否有因子的方法&#xff0c;因为那样的时间复杂度至少也是O(n)O(n)O(n)&#xff0c;空间复杂度是O(n)O(n)O(n)&#xff08;使用线性筛数法&#xff09;&#xff0c;时间复杂度还好说&#xff0c;空间复杂度…

bob-tong 字符串函数之Strtok()函数

https://www.cnblogs.com/Bob-tong/p/6610806.html Strtok()函数详解&#xff1a; 该函数包含在"string.h"头文件中 函数原型&#xff1a; char* strtok (char* str,constchar* delimiters ); 函数功能&#xff1a;   切割字符串&#xff0c;将str切分成一个个子…

数据链路层:SLIP(串型线路IP) PPP(点对点协议)

SLIP 没有差错控制, 传输时必须知道对方IP, 传输使用于低速业务 19.2k.应用非常受限 PPP协议 1. PPP协议功能 处理错误检测 支持多协议(IP, IPX, DECnet 等) 连接时允许协商 IP 地址 允许身份验证 2. PPP 的组成 串型链路上封装数据报, 即支持异步链路也支持面向 比特…

Honeycomb——BFS

【题目描述】 传送门 【题目分析】 看起来很复杂好像还要建图什么的&#xff0c;其实直接在原图上BFS就可以了&#xff0c;设置一下方向数组&#xff0c;然后直接跑就可以了。 【AC代码】 #include<cstdio> #include<cstring> #include<algorithm> #inc…

C语言中strspn()函数和strcspn()函数的对比使用

C语言strspn()函数&#xff1a;计算字符串str中连续有几个字符都属于字符串accept 头文件&#xff1a;#include <string.h> strspn() 函数用来计算字符串 str 中连续有几个字符都属于字符串 accept&#xff0c;其原型为&#xff1a; size_t strspn(const char *str, con…

Codeforces Round #587 (Div. 3)

A 只要每两个都不一样就可以&#xff0c;一旦出现两个一样的就改一个。 #include<cstdio> #include<cstring> #include<algorithm> #include<climits> #include<cctype> #include<queue> #include<set>using namespace std;typede…

信道分配 以太网

1.频分复用 将信道分为多个频带, 用户得到某个频带后,在通信的过程中, 自始至终都都占用这个信道.即频分复用中, 所有用户同时占用不同频带的信道 2. 时分信道 将时间划分为一段一段的等长时分复用帧, 每个用户在不同时间占用相同的数据帧 3. CSMA/CD 载波监听多点接入/碰撞…

strpbrk函数

http://blog.csdn.net/tommy_wxie/article/details/7554332 函数原型&#xff1a;extern char *strpbrk(char *str1, char *str2) 参数说明&#xff1a;str1待比较的字符串&#xff0c;str2为指定被搜索的字符串。 所在库名&#xff1a;#include <string.h> …

网络层网络层服务及其 IP 地址

ARP 协议功能 将 IP 地址通过广播(一个网段, 不能跨路由器), 目标 MAC 地址是FFFFFFFF 解析目标IP地址的 MAC 地址. IP 协议 网络层的一个协议, 是一个协议的统称, 包括 ARP(地址解析协议) 协议, ICMP(网络控制报文协议) 协议, IGMP(网际组管理协议) 协议. 其中 ICMP 和 IG…

随机生成1024个数,存入一段内存,用指针实现获取1024个数的最大数地址,最小数地址

http://blog.csdn.net/itcastcpp//details/39277193 题目&#xff1a;随机生成1024个数&#xff0c;存入一段内存&#xff0c;用指针实现获取1024个数的最大数地址&#xff0c;最小数地址&#xff0c;具体实现如下&#xff1a; [cpp] view plaincopy #include<stdlib.h> …

UVa11134

【题目分析】 觉得是一道挺考验贪心掌握程度的题目&#xff0c;我就算知道是要用贪心而且肯定和区间有关&#xff0c;肯定要进行一下排序什么的我还是没有找到合适的贪心策略。 经过大佬的博客后我才明白如何进行贪心。 如果没有任何提示看这道题&#xff0c;首先&#xff0…

传输层:IP 地址解析 路由转发

IP 地址与硬件地址 1. 地址解析 通过IP地址将其如何转换为 MAC 地址.解决同一个局域网上的主机或路由的 IP 地址和硬件地址的映射问题. 即以太网上除了主机还有路由. 即如果发出的请求所有的主机都没有做出相应, 那么该以太网上的路由会对其做出响应. (1) 以太网内部主机与…

UVa11582

一个数学问题,一旦出现循环确定循环节以后就能解决问题啦. 加上一个快速幂取模.需要注意的是数据范围是264,所以必须用unsigned long long才能解决问题. 觉得板子还是要会自己写,否则不同的题目具体有一些小的改变就会束手无策. 还有就是发现如果每次初始化数组的话就会超时,所…

输入一个单向链表,输出该链表中倒数第K个结点

http://blog.csdn.net/itcastcpp/article/details/39274891//尹成 单链表操作 #include <iostream> using namespace std; class LinkList;struct LinkNode { public:LinkNode(int value 0):m_value(value),pNext(NULL){}~LinkNode(){pNext NULL;}friend class LinkList…

网络层:构成超网(CIDR)

CIDR构成超网 CIDR消除了原来的传统的 A,B, C, D类地址, 使用了各种网络前缀来代替原来分类地址中的网络号和子网号, IP 地址由原来的三级分类又变成了两级分类. 其中网络号和子网号是一个随机的长度. 其中 CIDR 也可以使用 / 的形式来表示, 其中在 / 前面写上网络前缀的位数.…

UVa12169

我们可以暴力枚举a,然后通过x1和x3确定b的值&#xff0c;然后确定其他的数字&#xff0c;一旦出现错误就放弃这组解。 关键问题就在于如何通过a,x1,x3确定b的值 x2 ( x1 * a b) % M x3 ( x2 * a b ) % M ( ( x1 * a b ) % M * a b ) % M x3 - k * M x1 * a % M * a %…