2018-2019 ICPC 瀋陽站

https://codeforces.com/gym/101955

C題

題意:輸入n,k,q,問有多少1~n的排列,使得在把前k個按升序排好序後,最長上升子序列的長度不低於n-1.

暴力打表找規律,得出方程。

打表代碼:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <iterator>
using namespace std;
int num;
int f[10],b[10];
void dfs(int a[], int k, int m, int w){
	if (k==m) {
		copy(a+1, a+m+1, b+1);   //流迭代器
		// copy(b+1, b+m+1, ostream_iterator<int>(cout, " "));   //流迭代器
		// printf("\n");
		sort(b+1,b+w+1);
		for (int i=1; i<=m; i++) f[i]=1;
		for (int i=2; i<=m; i++){
			for (int j=i-1; j>=1; j--)
			{
				if (b[j]<b[i]){
					if (f[i]<f[j]+1)
						f[i]=f[j]+1;
				}
			}
		}
		// for (int i=1)
		// copy(f+1, f+m+1, ostream_iterator<int>(cout, " "));   //流迭代器
		// printf("\n");
		for (int i=1; i<=m; i++){
			if (f[i]>=m-1) {
				num++;
				break;
			}
		}
		// copy(a+1, a+m+1, ostream_iterator<int>(cout, " "));   //流迭代器
	}
	for (int i = k; i <= m; i++)
	{
		int tmp=a[k]; a[k]=a[i]; a[i]=tmp;
		dfs(a, k+1, m, w);
		tmp=a[k],a[k]=a[i],a[i]=tmp;
	}
}

int main()
{
	int a[10];
	for (int n=1; n<=5; n++){
		printf("%d:",n);
		for (int k=1; k<=n; k++){
			for (int i = 1; i <= n; i++) a[i]=i;
			num=0;
			dfs(a, 1, n, k);
			printf(" %d",num);
		}
		printf("\n");
	}

	return 0;
}

ac代碼:(注意特判k>n的情況,直接輸出n!)

#include<iostream>
#include<cstdio>
using namespace std;

int main()
{
	int _;
	long long n,k,q;
	scanf("%d",&_);
	for (int u=1; u<=_; u++){
		cin>>n>>k>>q;
		long long ans=1;
		if (k>n) {
			for (long long i=1; i<=n; i++){
				ans*=i;
				ans%=q;
			}
			printf("Case #%d: %I64d\n",u,ans);
		}
		else {
			for (long long i=1; i<=k; i++){
				ans*=i;
				ans%=q;
			}
			ans*=(1+k*(n-k)+(n-k)*(n-k-1));
			ans%=q;
			printf("Case #%d: %I64d\n",u,ans);
		}
	}

	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章