- 点击跳转专栏=>Unity3D特效百例
- 点击跳转专栏=>案例项目实战源码
- 点击跳转专栏=>游戏脚本-辅助自动化
- 点击跳转专栏=>Android控件全解手册
- 点击跳转专栏=>Scratch编程案例
- 点击跳转=>软考全系列
- 点击跳转=>蓝桥系列
👉关于作者
专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材、源码、游戏等)
有什么需要欢迎底部卡片私我,获取更多支持,交流让学习不再孤单。
👉实践过程
需要所有整理的文档可底部卡片联系我,直接发压缩包。
😜蚂蚁感冒
标题:蚂蚁感冒
长100厘米的细长直杆子上有n只蚂蚁。它们的头有的朝左,有的朝右。
每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒。
当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。
这些蚂蚁中,有1只蚂蚁感冒了。并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。
请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。
【数据格式】
第一行输入一个整数n (1 < n < 50), 表示蚂蚁的总数。
接着的一行是n个用空格分开的整数 Xi (-100 < Xi < 100), Xi的绝对值,表示蚂蚁离开杆子左边端点的距离。
正值表示头朝右,负值表示头朝左,数据中不会出现0值,也不会出现两只蚂蚁占用同一位置。
其中,第一个数据代表的蚂蚁感冒了。
要求输出1个整数,表示最后感冒蚂蚁的数目。
例如,输入:
3
5 -2 8
程序应输出:
1
再例如,输入:
5
-10 8 -20 12 25
程序应输出:
3
//c++
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
int n;
scanf("%d",&n);
int arr[n];
for (int i = 0; i < n; ++i) {
scanf("%d",&arr[i]);
}
int x = arr[0];
if(x>0){//向右
int ans=1;
for (int i = 0; i < n; ++i) {
if(arr[i]<0&&-arr[i]>x)//从右向左
ans++;
}
if(ans!=1)//有从右到左
for (int i = 0; i < n; ++i) {
if(arr[i]>0&&arr[i]<x)//从右向左
ans++;
}
printf("%d\n",ans);
}
if(x<0){//向左
// 左侧从左到右的
int ans=1;
for (int i = 0; i < n; ++i) {
if(arr[i]>0&&arr[i]<-x)
ans++;
}
if(ans!=1)
for (int i = 0; i < n; ++i) {
if(arr[i]<0&&-arr[i]>-x)
ans++;
}
printf("%d\n",ans);
}
return 0;
}
😜地宫取宝
标题:地宫取宝
X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。
地宫的入口在左上角,出口在右下角。
小明被带到地宫的入口,国王要求他只能向右或向下行走。
走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。
当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。
请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。
【数据格式】
输入一行3个整数,用空格分开:n m k (1<=n,m<=50, 1<=k<=12)
接下来有 n 行数据,每行有 m 个整数 Ci (0<=Ci<=12)代表这个格子上的宝物的价值
要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对 1000000007 取模的结果。
例如,输入:
2 2 2
1 2
2 1
程序应该输出:
2
再例如,输入:
2 3 2
1 2 3
2 1 5
程序应该输出:
14
//c++
#include <iostream>
#include <cstring>
using namespace std;
const int MOD = 1000000007;
int n, m, k;
int data[50][50];
long long ans;
long long cache[50][50][14][13];
void dfs(int x, int y, int max, int cnt) {
if (x == n || y == m || cnt > k)
return;
int cur = data[x][y];
if (x == n - 1 && y == m - 1)//已经面临最后一个格子
{
if (cnt == k || (cnt == k - 1 && cur > max)) {
ans++;
if (ans > MOD)
ans %= MOD;
}
}
if (cur > max) {//可以取这个物品
dfs(x, y + 1, cur, cnt + 1);
dfs(x + 1, y, cur, cnt + 1);
}
//对于价值较小,或者价值大但不去这个物品的情况如下
dfs(x, y + 1, max, cnt);
dfs(x + 1, y, max, cnt);
}
long long dfs2(int x, int y, int max, int cnt) {
// 查缓存
if (cache[x][y][max+1][cnt] != -1)
return cache[x][y][max+1][cnt];
long long ans = 0;
if (x == n || y == m || cnt > k)
return 0;
int cur = data[x][y];
if (x == n - 1 && y == m - 1)//已经面临最后一个格子
{
if (cnt == k || (cnt == k - 1 && cur > max)) {
ans++;
if (ans > MOD)
ans %= MOD;
}
return ans;
}
if (cur > max) {//可以取这个物品
ans += dfs2(x, y + 1, cur, cnt + 1);
ans += dfs2(x + 1, y, cur, cnt + 1);
}
//对于价值较小,或者价值大但不去这个物品的情况如下
ans += dfs2(x, y + 1, max, cnt);
ans += dfs2(x + 1, y, max, cnt);
cache[x][y][max+1][cnt]=ans % MOD;
return cache[x][y][max+1][cnt];
}
int main(int argc, const char *argv[]) {
scanf("%d %d %d", &n, &m, &k);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
scanf("%d", &data[i][j]);
}
}
// dfs(0, 0, -1, 0);//第一个点的价值可能是0
// printf("%d\n", ans);
memset(cache,-1, sizeof(cache));
printf("%lli\n", dfs2(0, 0, -1, 0));
return 0;
}
//java
public class _09地宫取宝 {
private static final int MOD = 1000000007;
static int[][] data;
private static int n;
private static int m;
private static int k;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
k = sc.nextInt();
data = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
data[i][j] = sc.nextInt();
}
}
for (int i = 0; i < 51; i++) {
for (int j = 0; j < 51; j++) {
for (int l = 0; l < 14; l++) {
for (int o = 0; o < 14; o++) {
cache[i][j][l][o] = -1;
}
}
}
}
long ans = dfs(0, 0, -1, 0);
System.out.println(ans);
}
static long[][][][] cache = new long[51][51][14][14];
private static long dfs(int x, int y, int max, int cnt) {
if (cache[x][y][max + 1][cnt] != -1) return cache[x][y][max + 1][cnt];
if (x == n || y == m || cnt > k) return 0;
int cur = data[x][y];
int ans = 0;
if (x == n - 1 && y == m - 1) {
if (cnt == k || (cnt == k - 1 && cur > max)) return 1;
return ans;
}
if (cur > max) {
ans += dfs(x, y + 1, cur, cnt + 1);
ans += dfs(x + 1, y, cur, cnt + 1);
}
ans += dfs(x, y + 1, max, cnt);
ans += dfs(x + 1, y, max, cnt);
cache[x][y][max + 1][cnt] = ans % MOD;
return ans;
}
}
😜波动数列
标题:波动数列
观察这个数列:
1 3 0 2 -1 1 -2 …
这个数列中后一项总是比前一项增加2或者减少3。
栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加a或者减少b的整数数列可能有多少种呢?
【数据格式】
输入的第一行包含四个整数 n s a b,含义如前面说述。
输出一行,包含一个整数,表示满足条件的方案数。由于这个数很大,请输出方案数除以100000007的余数。
例如,输入:
4 10 2 3
程序应该输出:
2
【样例说明】
这两个数列分别是2 4 1 3和7 4 1 -2。
【数据规模与约定】
对于10%的数据,1<=n<=5,0<=s<=5,1<=a,b<=5;
对于30%的数据,1<=n<=30,0<=s<=30,1<=a,b<=30;
对于50%的数据,1<=n<=50,0<=s<=50,1<=a,b<=50;
对于70%的数据,1<=n<=100,0<=s<=500,1<=a, b<=50;
对于100%的数据,1<=n<=1000,-1,000,000,000<=s<=1,000,000,000,1<=a, b<=1,000,000。
//java
public class _10波动数列 {
private static int n;
private static long s;
private static long a;
private static long b;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
s = sc.nextLong();
a = sc.nextLong();
b = sc.nextLong();
int t = n * (n - 1) / 2;
int[] dp = new int[t + 1];
dp[0] = 1;
for (int i = 1; i <= n - 1; i++) {
for (int j = i * (i + 1) / 2; j >= i; j--) {
// dp[j] += dp[j - i];
// if (dp[j] > 100000007) dp[j] %= 100000007;
dp[j] = (dp[j] + dp[j - i]) % 100000007;
}
}
long ans = 0;
for (int i = 0; i <= t; i++) {
if ((s - i * a + (t - i) * b) % n == 0)
ans = (ans + dp[i]) % 100000007;
// if (ans > 100000007) ans %= 100000007;
}
System.out.println(ans);
}
}
//c++
#include <iostream>
#include <vector>
#include <cstring>
#define MOD 100000007
using namespace std;
typedef long long LL;
int n, s, a, b;
long long ans;
void printPath(const vector<int> &path);
void solve1();
void dp1();
void dp2();
void dp3();
/**
*
* @param x 上一项
* @param cnt 截止上一项已经有多少个
* @param sum 截止上一项已经求得的和
*/
void dfs(LL x, int cnt, int sum, vector<int> path) {
if (cnt == n) {
if (sum == s) {
ans++;
}
// printPath(path);
if (ans > MOD)ans %= MOD;
return;
}
path.push_back(x + a);
dfs(x + a, cnt + 1, sum + x + a, path);
path.erase(path.end() - 1);
path.push_back(x - b);
dfs(x - b, cnt + 1, sum + x - b, path);
}
void printPath(const vector<int> &path) {
for (int i = 0; i < path.size(); ++i) {
cout << path[i] << " ";
}
cout << endl;
}
void solve2();
int main(int argc, const char *argv[]) {
scanf("%d %d %d %d", &n, &s, &a, &b);
// solve1();
// solve2();
// dp1();
// dp2();
dp3();
return 0;
}
/*一维数组*/
void dp3() {
int t = n * (n - 1) / 2;
int dp[t + 1];
memset(dp, 0, sizeof(dp));
dp[0] = 1;
for (int i = 1; i < n; ++i) {
for (int j = i * (i + 1) / 2; j >= i; --j) {//减少j的枚举
dp[j] = (dp[j] + dp[j - i]) % MOD;
}
}
for (LL ta = 0; ta <= t; ++ta) {
LL i = s - ta * a + (t - ta) * b;
if (i % n == 0)
(ans += dp[ta]) %= MOD;
}
cout << ans << endl;
}
/*2行的数组滚动使用*/
void dp2() {
int t = n * (n - 1) / 2;
int dp[2][t + 1];
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
dp[1][0] = 1;
int row = 0;
for (int i = 1; i < n; ++i) {
row = 1 - row;
for (int j = 1; j <= i * (i + 1) / 2; ++j) {//这里可以减少枚举
if (i > j) dp[row][j] = dp[1 - row][j] % MOD;
else dp[row][j] = (dp[1 - row][j] + dp[1 - row][j - i]) % MOD;
}
}
// 必须用LL,因为s+tb有可能超出int 10^9+10^6*10^6
for (LL ta = 0; ta <= t; ++ta) {
LL i = s - ta * a + (t - ta) * b;
if (i % n == 0)
(ans += dp[row][ta]) %= MOD;//选择性地累加最后一行
}
cout << ans << endl;
}
void dp1() {
int t = n * (n - 1) / 2;//最终式子中a或b的最大的个数(系数)
int dp[n][t + 1];
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for (int i = 0; i < n; ++i) {
dp[i][0] = 1;
}
for (int i = 1; i < n; ++i) {
for (int j = 1; j <= t; ++j) {
if (i > j) dp[i][j] = dp[i - 1][j] % MOD;
else dp[i][j] = (dp[i - 1][j] + dp[i - 1][j - i]) % MOD;
}
}
for (LL ta = 0; ta <= t; ++ta) {
LL i = s - ta * a + (t - ta) * b;
if (i % n == 0)
(ans += dp[n - 1][ta]) %= MOD;
}
cout << ans << endl;
}
void solve2() {
int t = n * (n - 1) / 2;
LL x;
LL x1 = (s - a * t) / n;
LL x2 = (s + b * t) / n;
// 枚举首项
for (x = x1; x <= x2; x++) {
// 对x进行初步检测,有的x,无论怎么搭配a,b的数目,都不能得出s
for (int ta = 0; ta <= t; ++ta) {//枚举a的数目[0,t]
LL cal = x * n + ta * a - (t - ta) * b;
if (cal == s) {//减少对x的枚举
vector<int> path;
path.push_back(x);
dfs(x, 1, x, path);
}
}
}
printf("%lli\n", ans);
}
void solve1() {
int t = n * (n - 1) / 2;//最终式子中a或b的最大的个数(系数)
LL x;
// 枚举首项
LL x1 = (s - a * t) / n;
LL x2 = (s + b * t) / n + 1;
for (x = x1; x <= x2; x++) {
vector<int> path;
path.push_back(x);
dfs(x, 1, x, path);
}
printf("%lli\n", ans);
}
😜李白打酒
标题:李白打酒
话说大诗人李白,一生好饮。幸好他从不开车。
一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:
无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。
这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。
请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。
像这样的答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)。
//c++
#include <iostream>
using namespace std;
int ans;
void f(int dian, int hua, int jiu) {
if (dian == 0 && hua == 0 && jiu == 1)
ans++;
if (dian > 0) f(dian - 1, hua, jiu * 2);
if (hua > 0) f(dian, hua - 1, jiu - 1);
}
int main(int argc, const char *argv[]) {
f(5, 9, 2);
cout << ans << endl;
return 0;
}
//java
public class _02李白打酒 {
private static int ans;
public static void main(String[] args) {
f(5, 9, 2);
System.out.println(ans);
}
private static void f(int dian, int hua, int jiu) {
if (dian == 0 && hua == 0 && jiu == 1) ans++;
if (dian > 0) f(dian - 1, hua, jiu * 2);
if (hua > 0) f(dian, hua - 1, jiu - 1);
}
}
👉其他
📢作者:小空和小芝中的小空
📢转载说明-务必注明来源:https://zhima.blog.csdn.net/
📢这位道友请留步☁️,我观你气度不凡,谈吐间隐隐有王者霸气💚,日后定有一番大作为📝!!!旁边有点赞👍收藏🌟今日传你,点了吧,未来你成功☀️,我分文不取,若不成功⚡️,也好回来找我。
温馨提示:点击下方卡片获取更多意想不到的资源。