2023NEUQACM Week3

必做题


P1028 [NOIP2001 普及组] 数的计算

找规律递推即可。
完整代码如下:

#include<iostream>
using namespace std;
int arr[1001], sum[1001];
int main()
{
    arr[1] = 1;
    sum[1] = 1;
    int n;
    cin >> n;
    for(int i=2 ; i<=n ; i++)
    {   
        arr[i] = 1 + sum[i/2];
        sum[i] = sum[i-1] + arr[i];
    }
    cout << arr[n];
    return 0;
}

P1192 台阶问题

递推即可。
完整代码如下:

#include<bits/stdc++.h>
using namespace std;

int steps[100005];
int main()
{
	// freopen("D:\\test.txt","r",stdin);
	int n,k;
	cin>>n>>k;
	steps[0] = 1;
	for(int i=0 ; i<n ; i++){
		for(int j=i+1 ; j-i<=k&&j<=n ; j++){
			steps[j] += steps[i];
			steps[j] %= 100003;
		}
	}
	cout << steps[n];
	return 0;
}

P1044 [NOIP2003 普及组] 栈

分析:对于序列数 n n n 欲求 f ( n ) f(n) f(n) ,当 k k k 是其输出序列的最后一个数时,比 k k k 小的数在 k k k 进栈时已经全部出栈,比 k k k 大的数在 k k k 出栈时已经全部出栈,二者互相独立,满足分布乘法计数原理,即 f ( k − 1 ) ∗ f ( n − k ) , ( 1 ≤ k ≤ n ) f(k-1)*f(n-k),(1\le k\le n) f(k1)f(nk)(1kn) 于是我们可以写成一个卷积的形式(Catalan数):
f ( n ) = ∑ k = 1 n f ( k − 1 ) ∗ f ( n − k ) f(n)=\sum_{k=1}^{n}f(k-1)*f(n-k) f(n)=k=1nf(k1)f(nk)
完整代码如下:

#include<bits/stdc++.h>
using namespace std;

int st[20]; 
int main()
{
	// freopen("D:\\test.txt","r",stdin);
	int n; 
	cin>>n;
	st[0] = st[1] = 1;
	for(int i=2 ; i<=n ; i++)
		for(int j=0 ; j<=i ; j++)
			st[i] += st[i-1-j]*st[j];
	cout << st[n];
	return 0;
}

P1003 [NOIP2011 提高组] 铺地毯

从后向前看 ( x , y ) (x,y) (x,y) 在不在地毯上就行。
完整代码如下:

#include<bits/stdc++.h>
using namespace std;
struct carpet{
	int a,b,g,k;
}arr[10004];
int main()
{
	// freopen("D:\\test.txt","r",stdin);
	int n,x,y;
	cin>>n;
	for(int i=1; i<=n ;i++) cin>>arr[i].a>>arr[i].b>>arr[i].g>>arr[i].k;
	cin>>x>>y;
	int i;
	for(i=n ; i>=1 ; i--){
		if(x>=arr[i].a && x<=arr[i].a+arr[i].g 
		&& y>=arr[i].b && y<=arr[i].b+arr[i].k){
			cout << i;
			break;
		}
	}
	if(i==0) cout << -1;
	return 0;
}

选做题


P4994 终于结束的起点

暴力枚举即可。
完整代码如下:

#include<bits/stdc++.h>
using namespace std;

int fib[0x9fffff];
int main()
{
	// freopen("D:\\test.txt","r",stdin);
	int m,ans;
	cin>>m;
	fib[0]=0, fib[1]=1;
	for(int i=2 ; i<0x9fffff ; i++){
		fib[i] = (fib[i-1] + fib[i-2]) % m;
		if(fib[i-1]==0 && fib[i]==1){
			ans = i-1;
			break;
		}
	}
	cout << ans;
	return 0;
}

P2615 [NOIP2015 提高组] 神奇的幻方

按照题意写一个模拟,凑合凑合过了。
完整代码如下:

#include<bits/stdc++.h>
using namespace std;

int arr[50][50];
struct Pos{
	int row,col;
}pos[2500];

int main()
{
	// freopen("D:\\test.txt","r",stdin);
	int n;
	cin>>n;
	arr[1][(n+1)/2] = 1;
	pos[1].row=1, pos[1].col=(n+1)/2;
	for(int i=2 ; i<=n*n ; i++){
		if(pos[i-1].row==1 && pos[i-1].col!=n){
			pos[i].row=n, 
			pos[i].col=pos[i-1].col + 1;
			arr[pos[i].row][pos[i].col] = i;
		}
		else if(pos[i-1].row!=1 && pos[i-1].col==n){
			pos[i].row=pos[i-1].row - 1, 
			pos[i].col=1;
			arr[pos[i].row][pos[i].col] = i;
		}
		else if(pos[i-1].row==1 && pos[i-1].col==n){
			pos[i].row=2, 
			pos[i].col=n;
			arr[pos[i].row][pos[i].col] = i;
		}
		else{
			if(arr[pos[i-1].row-1][pos[i-1].col+1]==0){
				pos[i].row=pos[i-1].row-1, 
				pos[i].col=pos[i-1].col+1;
				arr[pos[i].row][pos[i].col] = i;
			}
			else{
				pos[i].row=pos[i-1].row+1, 
				pos[i].col=pos[i-1].col;
				arr[pos[i].row][pos[i].col] = i;
			} 
		}
	}
	for(int i=1 ; i<=n ; i++){
		for(int j=1 ; j<=n ; j++)
			cout << arr[i][j] << " ";
		cout << '\n';
	}
	return 0;
}

P1011 [NOIP1998 提高组] 车站

因为不知道第二站上下车的人数,不妨设为 b b b,暴力枚举 b b b 直到找到答案。
完整代码如下:

#include<bits/stdc++.h>
using namespace std;

struct ninzu{
	int on,off,tot;
}hito[25];
int main()
{
	// freopen("D:\\test.txt","r",stdin);
	int n,m,x;
	cin>>hito[1].on>>n>>m>>x;
	hito[1].tot = hito[2].tot = hito[1].on; 
	hito[1].off = 0;
	for(int b=0 ; b<=20 ; b++){ 
		// 不放心可以枚举更大的范围,本题认为b<=20就可以过数据点了
		hito[2].on = hito[2].off = b;
		for(int i=3 ; i<=n ; i++){
			hito[i].on = hito[i-1].on + hito[i-2].on;
			hito[i].off = hito[i-1].on;
			hito[i].tot = hito[i-1].tot + hito[i].on - hito[i].off;
		}
		if(hito[n-1].tot == m){
			cout << hito[x].tot;
			break;
		}
	}
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值