寒假训练24号

F - 6 HDU - 1016
深搜问题DFS
//题意:1-n个数排列,使相邻或首位两个数之和为素数,按字典顺序打印结果。

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

int n;
int b[25];  //访问标记,下标对于所表示的数字,元素值0为未使用,1为已使用
int num[25];

int prime(int a)  //判断素数
{
	for (int i = 2; i <= sqrt(a); ++i)
	{
		if (a%i == 0)
		{
			return 0;
		}
	}
	return 1;
}

void dfs(int k)  //0-20

{
	if (k == n && prime(num[k] + num[1])==1)  //深度K到了n,并且最后一个和第一个也满足条件
	{
		for (int i = 1; i < n; ++i)
		{
			cout << num[i] << ' ';  //输出结果
		}			
		cout << num[n]<< endl;  //注意最后一个数字后面不能有空格
	}
	else
	{
		for (int i = 2; i <= n; ++i)
		{
			if (b[i]==0 && prime(num[k] + i)==1)  //i没被用过,并且放入能满足条件
			{
				num[k + 1] = i;   //放入
				b[i] = 1;   //标记为已用
				dfs(k + 1);   //进行下一深度
				b[i] = 0;  //若回溯了则消除标记
			}
		}
	}
}

int main()
{	
	int caseN = 1;
	while (cin >> n)
	{
		memset(b, sizeof(b), 0);
		num[1] = 1;
		b[1] = 1;
		cout << "Case " << caseN << ":" << endl;
		++caseN;
		dfs(1);
		cout << endl;
	}
	return 0;
}

H - 8 UVA - 11264
贪心问题——最大硬币种类

#include <iostream>
using namespace std;

int main()
{
	int p[1005];
	int T, n;
	cin >> T;
	while (T--)
	{
		cin >> n;
		for (int i = 0; i < n; ++i)
		{
			cin >> p[i];
		}
		if (n == 1 || n == 2) cout << n << endl;
		else
		{
			int s = p[0];
			int N = 2;
			for (int i = 1; i < n - 1; ++i)
			{
				if (s < p[i] && s + p[i] < p[i + 1])
				{
					s += p[i];
					++N;
				}
			}
			cout << N << endl;
		}
	}
}

I - 9 HDU - 2068
错排问题

#include <iostream>
using namespace std;

long long list[25]={1,0};//要用long long

void D()//求i个数错排有多少种
{
	for(int i=2;i<=25;i++)
		list[i]=(i-1)*(list[i-1]+list[i-2]);
}

long long c(int n,int m)  //组合数
{
	long long s=1;
	for(int i=1;i<=m;i++)
		s=s*(n-i+1)/i;
	return s;
}

int main()
{
	D();
	int n;
	long long total;
	while(cin>>n,n)
	{
		total=0;
		for(int i=0;i<=n/2;i++)   
		{
			total+=c(n,i)*list[i];
		}
		cout<<total<<endl;
	}
}

J - 0 HDU - 1166
//线段树
思路:建树(理解好下标,及递归过程)、add和sub使用同一个函数,从上往下更新数据、query查询过程理解好,以后可直接套用模板
ps:输入数据量大时应用scanf_s避免超时,注意字母l和数字1,在编译器宋体下容易认错!!!

#include <iostream>
using namespace std;

const int maxn = 50005;
int n;  //n个数
int p[50005];
int s;
struct node
{
	int l;
	int r;
	int sum;
}t[maxn<<2];

void build(int l, int r,int idx	)  //l:左边界,r:右边界,idx:下标
{
	t[idx].l = l;
	t[idx].r = r;
	if (l==r)
	{
		t[idx].sum = p[l];
		return;
	}
	else
	{
		int mid = (t[idx].l + t[idx].r) >> 1;
		build(l, mid, (idx << 1) + 1);  //左子树;重点理解下标idx的变化
		build(mid + 1, r, (idx << 1) + 2);  //右子树
		t[idx].sum = t[(idx << 1) | 1].sum + t[(idx << 1) + 2].sum;
	}
}

void query(int l, int r, int idx)  //查询
{
	if (l <= t[idx].l&&r >= t[idx].r)
	{	
	//	cout << "s=s+t[idx].sum=" << s << '+' << t[idx].sum<<endl;
		s += t[idx].sum;
	}

	else
	{
		int mid = (t[idx].l + t[idx].r) >> 1;
		if (r <= mid)
		{
			query(l, r, (idx << 1) | 1);
		}
		else if (l > mid)
		{
			query(l, r, (idx << 1) + 2);
		}
		else
		{
			query(l,mid, (idx << 1) | 1);  //
			query(mid+1, r, (idx << 1) + 2);  //
		}
	}
}

void update(int i, int idx, int val)
{
	t[idx].sum += val;
	if (t[idx].l == i && i == t[idx].r) return;
	else
	{
		int mid = (t[idx].l + t[idx].r) >> 1;
		if (i <= mid) update(i, (idx << 1) | 1, val);
		else update(i, (idx << 1) +2, val);
	}
}

int main()
{
	int ans = 1;
	int T;
	cin >> T;
	while (T--)
	{
		cout << "Case " << ans++<<":" << endl;
		cin >> n;
		for (int i = 1; i <= n; ++i)
		{
			cin >> p[i];
		}
		build(1, n, 0);
	/*	for (int i = 0; i < 30; ++i)
		{
			cout << t[i].sum << ' ';
		}cout << endl;*/
		char op[10];
		while (	cin>>op)
		{
			if (op[0] == 'E') break;
			int a, b;
			scanf_s("%d %d", &a, &b);
		//	cin >> a >> b;  //超时
			if (op[0] == 'Q')
			{
				s = 0;
				query(a, b, 0);
				printf("%d\n", s);
		//		cout << s << endl;
			}
			else if (op[0] == 'A')
			{
				update(a, 0, b);
			}
			else if (op[0] == 'S')
			{
				update(a, 0, -b);
			}
		/*	for (int i = 0; i < 30; ++i)
			{
				cout << t[i].sum << ' ';
			}cout << endl<<endl;*/
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浅若清风cyf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值