哈哈

C~K的魔法石

Time Limit: 1000 ms  Memory Limit: 65536 KiB
Problem Description

传说 C~K 有三种神奇的魔法石:第一种魔法石叫做人铁石,拥有 A 的能量;第二种魔法石叫做地冈石,拥有 B 的能量;而第三种,则是最神奇的天玄石,拥有无可比拟的 C 的能量!

 

但是有一天,小豪宝宝 (UMR) 太调皮了,把一颗天玄石玩丢了……

 

“这可玩大发了,这样我会被 C~K 责备的。”小豪宝宝悲伤的说到,“怎么办呢?”

 

这时候小豪宝宝望了望窗外的飞过的白鸽,突然急中生智,想到了一个办法:干脆就用人铁石和地冈石把天玄石凑出来吧!

 

“只要我拿若干个人铁石,若干个地冈石,他们的能量之和,恰好加起来等于天玄石所拥有的能量。然后再把这些石头粘在一起,那么由若干个石头的组成的整体,我不就可以看做是一个天玄石了吗?“

 

小豪宝宝愈发觉得自己机智。

 

所以现在有一个问题摆在你的面前了,给你 A, B, C,请判断是否存在两个大于等于 0 的整数 x, y 满足 Ax+By=C。

Input

第一行一个 T,表示有 T 组测试数据。

接下来 T 行,每行三个整数 a, b, c,分别表示三块石头的能量值。

满足 (1 ≤ T ≤ 100, 1 ≤ a,  b ≤ 100, 1 ≤ c ≤ 10 000)。

Output

对每一组测试答案均需要输出结果,如果可行的话,输出 "Yes",否则输出 "No"(不包括引号)。

Sample Input
2
1 2 3
4 6 15
Sample Output
Yes
No

    
#include <stdio.h>
02#include <iostream>
03using namespace std;
04int main()
05{
06    int t;
07    cin>>t;
08    while(t--)
09    {
10        int a,b,c;
11        cin>>a>>b>>c;
12        int h=c/a;
13    //表示出边界如果从如果单独乘i已经大了
14        bool flag=false;
15        for(int i=0; i<=h; i++)
16        {
17            int k1=a*i;//暴力,模拟
18            if((c-k1)%b==0)
19            {
20                flag=true;
21                break;
22            }
23        }
24        if(flag)
25 
26            printf("Yes\n");
27 
28        else
29 
30            printf("No\n");
31 
32    }
33    return 0;
34}
暴力一发就好了,枚举 A,看看有没有满足条件的 B

C~K的奖券

Time Limit: 1000 ms  Memory Limit: 65536 KiB
Problem Description

超市举行兑奖活动啦!!!

C~K 费劲心力,终于搞到了 m 张兑奖券,而奖品区有 n 件奖品,分别标号为 1~n,其中第 i 件奖品需要 need(i) 张奖券进行兑换,同时也只能兑换一次,为了辛苦得到的奖券不能够浪费,C~K 给每件奖品都评了分,其中第i件奖品的评分值为 value(i),表示 C~K 对这件奖品的喜好值,现在他想知道,凭借他手上的这些奖券,可以换到哪些奖品,使得这些奖品的喜好值最大。

Input

输入数据有多组(数据组数不超过 100),到 EOF 结束。

每一组测试数据第一行为两个正整数 n, m。表示奖品的个数及 C~K 手中的奖券数。

接下来 n 行描述每一行描述一个奖品,其中第 i 行为两个整数 need(i) 和 value(i),意义如前文所述。

(0 < n <= 500, 0 < m <= 10^5, 0 < need(i) <= 2*10^5, 0 < value(i) <= 10^3)

Output

对于每组输入的数据输出一个整数 ans,代表 C~K可 以获得的总喜好值。

Sample Input
1 3
1 1
Sample Output

1

我们很容易的就想到了记忆化搜索,我们用 best(n, m) 来表示有 n 件物品,奖券为 m 的张的时候,C~K 可以得到的最大的喜好值,那么我们只需要决定第 n 件物品选不选就可以了,所以我们很容易的就可以得到状态转移方程 best(n, m) = max(best(n-1, m), best(n, m-need(i))+value),分别对应着选与不选两种情况,但是现在又有一个问题,如果把 best 开成一个二维数组的话好像空间有点撑不太住,所以我们继续优化,我只需要开一个 m 大小的一维数组就可以了,如果我按照 j 从 m到 1 的顺序,也就是跟之前相反的顺序来进行计算的话,另外根据我们的状态转移方程,可以显然得出如果状态 (iA, jA) 依赖于状态 (iB, jB),那么肯定有 iA=iB+1, jA>jB,所以不难得出一个结论,我们在计算 best(i, j) 的时候,因为 best(i, j+1…m) 这些状态已经被计算过了,所以就意味着 best(i-1,k), k = j…m 这些值就都没有用了–所以依赖于他们的值都已经计算完了,于是他们原有的储存空间都可以用来春村别的东西,所以我们不妨就直接将 best(i, j) 的值存在 best(i-1, j) 原有的位置上,详见代码。



#include <bits/stdc++.h>
02#define MAXN 1000007
03int a[MAXN],need[MAXN],val[MAXN];
04using namespace std;
05int main()
06{
07    int n,m;
08    while(~scanf("%d%d",&n,&m))
09    {
10        for(int i=1; i<=n; i++)
11            scanf("%d%d",&need[i],&val[i]);
12            memset(a,0,sizeof(a));
13        for(int i=1; i<=n; i++)
14            for(int j=m; j>=need[i]; j--)
15                a[j]=max(a[j],a[j-need[i]]+val[i]);
16        cout<<a[m]<<endl;
17    }
18    return 0;
19}
20 
类似背包,

#include <bits/stdc++.h>
02#define MAXN 1000007
03int a[MAXN],need[MAXN],val[MAXN];
04using namespace std;
05int main()
06{
07    int n,m;
08    while(~scanf("%d%d",&n,&m))
09    {
10        for(int i=1; i<=n; i++)
11            scanf("%d%d",&need[i],&val[i]);
12            memset(a,0,sizeof(a));
13        for(int i=1; i<=n; i++)
14            for(int j=m; j>=need[i]; j--)
15                a[j]=max(a[j],a[j-need[i]]+val[i]);
16        cout<<a[m]<<endl;
17    }
18    return 0;
19}
20 

#include <bits/stdc++.h>
02#define MAXN 1000007
03int a[MAXN],need[MAXN],val[MAXN];
04using namespace std;
05int main()
06{
07    int n,m;
08    while(~scanf("%d%d",&n,&m))
09    {
10        for(int i=1; i<=n; i++)
11            scanf("%d%d",&need[i],&val[i]);
12            memset(a,0,sizeof(a));
13        for(int i=1; i<=n; i++)
14            for(int j=m; j>=need[i]; j--)
15                a[j]=max(a[j],a[j-need[i]]+val[i]);
16        cout<<a[m]<<endl;
17    }
18    return 0;
19}
20 

Ultimate Array

Time Limit: 1000 ms  Memory Limit: 65536 KiB
Problem Description

bLue 这次又获得了一个更厉害的数组,欣喜之余,他想知道某个数字在数组中出现了多少次,你能帮助他吗?

Input

输入数据有多组(数据组数不超过 20),到 EOF 结束。

对于每组数据:

  • 第 1 行输入 2 个用空格隔开的整数 n, q (1 <= n, q <= 10^5),分别表示数组中数字的个数和询问的次数。
  • 第 2 行输入 n 个用空格隔开的整数 ai (0 <= ai <= 10^9),表示数组中的数字。
  • 接下来 q 行,每行输入一个整数 v (0 <= v <= 10^9),表示要询问的数字。
Output

对于每组数据:

  • 每次询问输出一行,包含一个整数,表示 bLue 询问的数字在数组中出现的次数。
  • 每组数据末尾输出一行空行。
Sample Input
6 4
2 0 2 666 666 2
0
2
666
7
Sample Output
1
3
2
0



01#include<bits/stdc++.h>
02struct node
03{
04    int data;
05    struct node *next;
06}*h[100000];//哈希表链式存储
07int a[100000], n;
08void creat(int x)
09{
10    node *p;
11    int i;
12    i = x % n;//对它取余,将x存到 i下标的 链表里面
13    p = new node;
14    p->data = x;
15    p->next = h[i];//插入到头
16    h[i] = p;
17}
18int find(int x)
19{
20    node *p;
21    int i, num = 0;
22    i = x % n;
23    for(p = h[i]; p; p = p->next)//暴力查找
24    {
25        if(p->data == x)//找到相同的于x 统计出现的次数
26            num++;
27    }
28    return num;//返回出现的次数
29}
30int main()
31{
32    int i, m, num;
33    while(~scanf("%d %d", &n, &m))
34    {
35        for(i = 0; i < n; i++)
36        {
37            h[i] = NULL;//初始化每个下标的头,可以暴力free掉
38        }
39        for(i = 0; i < n; i++)
40        {
41            scanf("%d", &a[i]);
42            creat(a[i]);//储存进hash
43        }
44        while(m--)
45        {
46            scanf("%d", &num);
47            printf("%d\n", find(num));//输出出现的次数
48        }
49        printf("\n");
50    }
51    return 0;
52}

#include <bits/stdc++.h>
02#define MAXN 1000007
03int a[MAXN],need[MAXN],val[MAXN];
04using namespace std;
05int main()
06{
07    int n,m;
08    while(~scanf("%d%d",&n,&m))
09    {
10        for(int i=1; i<=n; i++)
11            scanf("%d%d",&need[i],&val[i]);
12            memset(a,0,sizeof(a));
13        for(int i=1; i<=n; i++)
14            for(int j=m; j>=need[i]; j--)
15                a[j]=max(a[j],a[j-need[i]]+val[i]);
16        cout<<a[m]<<endl;
17    }
18    return 0;
19}
20 

我已经是一只废桔了

Time Limit: 1000 ms  Memory Limit: 65536 KiB
Problem Description

在古老而神秘的 409 实验室,住着一位史诗级长者,世人称之为「金桔」。

金桔能歌善舞,能说会道,能写伸展树,会敲自动机,口算微积分,心算大反演,区域赛虐遍全场,傲得了娇卖得了萌,实乃 ACM 界之集大成长者

最近,临近退役的金桔自觉体弱多衰,身子骨一日不如一日,常常自言自语道:“唉,我已经是一只废桔了...”。现在,他连基本的查找大于等于 n 的素数都不会了,为了冲 Final,他只能求助于你,你能帮助金桔吗?

Input

输入数据有多组(数据组数不超过 100000),到 EOF 结束。

每组数据输入一行,包含一个整数 n (0 <= n < 5000000)。

Output

对于每组数据,输出一行,包含用空格隔开的两个整数 i, v,表示大于或等于 n 的第一个素数的相关信息。其中 i 表示此素数是第几个素数,v 表示此素数是多少。

Sample Input
1
2
3
4
1024
2333
Sample Output
1 2
1 2
2 3
3 5
173 1031
345 2333

#include <stdio.h>
#include <stdbool.h>

#define MAXN 5000000

int prime[1000000], cnt = 1;
bool is_composite[MAXN];

// 素数筛
void Sieve() {
	for(int i=2; i<MAXN; ++i) {
		if(!is_composite[i]) prime[cnt++] = i;
		for(int j=1; j<cnt && i*prime[j]<MAXN; ++j) {
			is_composite[i*prime[j]] = true;
			if(i%prime[j] == 0) break;
		}
	}
}

// 二分查找
int BinarySearch(int a[], int low, int high, int key) {
	int mid = (low+high)/2;
	if(low >= high) return low;
	else {
		if(key < a[mid])
			return BinarySearch(a, low, mid-1, key);
		else if(key > a[mid])
			return BinarySearch(a, mid+1, high, key);
		else return mid;
	}
}

int main() {
	Sieve();
	int n;
	while(~ scanf("%d", &n)) {
		int idx = BinarySearch(prime, 1, cnt, n);
		if(prime[idx] < n) idx++;
		printf("%d %d\n", idx, prime[idx]);
	}
	
	return 0;
}

bLue的旅行

Time Limit: 1000 ms  Memory Limit: 65536 KiB
Problem Description

一天,刚打完 CF 的 bLue 决定来一场说走就走的旅行,于是他拿出了地图开始制定行程。

在地图上,bLue 和目的地之间可以用一条直线来表示,他自己在坐标为 0 的位置,而目的地在坐标为 n 的位置。

bLue 计划花费 d 天到达目的地,旅途中,他每天只能选择前进 1, 2, 3 或 4 个单位距离,而不能向回走。他想知道有多少种方案能使他恰好花费 d 天到达目的地。

例如:目的地的坐标为 4,计划天数为 3,则 bLue 有 "1, 2, 4", "1, 3, 4", "2, 3, 4" 三种方案。

Input

输入数据有多组(数据组数不超过 10000),到 EOF 结束。

每组数据输入一行,包含 2 个整数 n, d (0 <= n <= 20, 0 <= d < 10^6),分别代表目的地的位置和 bLue 花费的天数。

Output

对于每组数据,输出一行,代表方案数。

Sample Input
2 1
2 2
4 2
4 3
5 3
Sample Output
1
1
3
3
6
// DFS Version

#include <stdio.h>

int n, d, now_n, now_d, ans;

void DFS(int now_n, int now_d) {
	if(now_n > n) return;
	if(now_d > d) return;
	if(now_n==n && now_d==d) {
		ans++;
		return;
	}
	// 向下一步的四种情况递归
	DFS(now_n+1, now_d+1);
	DFS(now_n+2, now_d+1);
	DFS(now_n+3, now_d+1);
	DFS(now_n+4, now_d+1);
}

int main() {
	while(~ scanf("%d %d", &n, &d)) {
		if(d > n) { // d > n 直接输出 0
			printf("0\n");
			continue;
		}
		ans = 0; // ans 记录答案
		DFS(0, 0);
		printf("%d\n", ans);
	}
	
	return 0;
}


// DP Version

#include <stdio.h>

int max(int a, int b) {
	return a>b ? a : b;
}

int main() {
	int n, d, dp[21][21] = {0};
	dp[0][0] = 1;
	for(int i=1; i<=20; ++i) {
		for(int j=1; j<=20; ++j) {
			for(int k=max(i-4,0); k<=i-1; ++k) { // 上一天所在的位置只能是 i-4 到 i-1
				dp[i][j] += dp[k][j-1];
			}
		}
	}
	while(~ scanf("%d %d", &n, &d)) {
		if(d > n) { // d > n 直接输出 0
			printf("0\n");
			continue;
		}
		printf("%d\n", dp[n][d]);
	}
	
	return 0;
}
// DP Version

#include <stdio.h>

int max(int a, int b) {
	return a>b ? a : b;
}

int main() {
	int n, d, dp[21][21] = {0};
	dp[0][0] = 1;
	for(int i=1; i<=20; ++i) {
		for(int j=1; j<=20; ++j) {
			for(int k=max(i-4,0); k<=i-1; ++k) { // 上一天所在的位置只能是 i-4 到 i-1
				dp[i][j] += dp[k][j-1];
			}
		}
	}
	while(~ scanf("%d %d", &n, &d)) {
		if(d > n) { // d > n 直接输出 0
			printf("0\n");
			continue;
		}
		printf("%d\n", dp[n][d]);
	}
	
	return 0;
}

bLue的文件查找器

Time Limit: 1000 ms  Memory Limit: 65536 KiB
Problem Description

bLue 的电脑里存了各种各样的文件,随着文件越来越多,查找文件也成了一个麻烦事。

现在,他想要查找所有指定格式(扩展名)的文件,不过他并不会使用文件管理器自带的搜索功能,所以他想求你写一个文件查找器,来帮他查找所有指定格式的文件。

Input

输入数据有多组(数据组数不超过 100),到 EOF 结束。

对于每组数据:

  • 第一行输入一个整数 n (1 <= n <= 100) 和一个长度不超过 5 的字符串 ex,分别表示文件夹内的文件数量和要查找的文件的扩展名。
  • 接下来的 n 行,每行输入一个完整文件名。保证文件名不包含空格且长度不超过 100。
Output

对于每组数据,按照输入顺序输出文件夹内所有扩展名符合查找要求的文件名。

Sample Input
6 cpp
3717.cpp
xunhuansai_daima.zip
xunhuansai_jietibaogao.pdf
C.cpp
bLue.jpg
cyk_de_richang.mp4
Sample Output
3717.cpp
C.cpp
// DP Version

#include <stdio.h>

int max(int a, int b) {
	return a>b ? a : b;
}

int main() {
	int n, d, dp[21][21] = {0};
	dp[0][0] = 1;
	for(int i=1; i<=20; ++i) {
		for(int j=1; j<=20; ++j) {
			for(int k=max(i-4,0); k<=i-1; ++k) { // 上一天所在的位置只能是 i-4 到 i-1
				dp[i][j] += dp[k][j-1];
			}
		}
	}
	while(~ scanf("%d %d", &n, &d)) {
		if(d > n) { // d > n 直接输出 0
			printf("0\n");
			continue;
		}
		printf("%d\n", dp[n][d]);
	}
	
	return 0;
}

#include <stdio.h>
#include <string.h>

int main() {
	int n;
	char s[101], s_ex[6], ex[6];
	while(~ scanf("%d %s", &n, ex)) {
		for(int i=0; i<n; ++i) {
			scanf("%s", s);
			for(int i=0; s[i]; ++i) {
				if(s[i] == '.') {
					strcpy(s_ex, s+i+1); // 截取扩展名到 s_ex
					if(!strcmp(s_ex, ex)) printf("%s\n", s);
					break;
				}
			}
		}
	}
	
	return 0;
}


// DP Version

#include <stdio.h>

int max(int a, int b) {
	return a>b ? a : b;
}

int main() {
	int n, d, dp[21][21] = {0};
	dp[0][0] = 1;
	for(int i=1; i<=20; ++i) {
		for(int j=1; j<=20; ++j) {
			for(int k=max(i-4,0); k<=i-1; ++k) { // 上一天所在的位置只能是 i-4 到 i-1
				dp[i][j] += dp[k][j-1];
			}
		}
	}
	while(~ scanf("%d %d", &n, &d)) {
		if(d > n) { // d > n 直接输出 0
			printf("0\n");
			continue;
		}
		printf("%d\n", dp[n][d]);
	}
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值