比赛落下的题
问题 C: 小李发奖金
题目描述
当然打台球只是小李的休闲娱乐活动,对待他的本职工作,他还是非常兢兢业业的。但是小李的老板是个周扒皮,每次都想克扣小李的工资和奖金,甚至制定出非常奇葩的规则。
又到了每年发年终奖的时候了,今年老板的规则是这样的:给你n个数,每次你可以对任意一个数加1,直到所有的数都不相等为止,每加一次都要花费一定数额的费用。为了小李的幸福生活,聪明的你可否帮助小李,让他尽量少扣钱。
输入
第一行n(1<=n<=30000),表示共有n个数。
第二行共n个用空格隔开的非负整数ai(ai<=1000000)。
输出
仅一个整数,表示加到让每个数都不相等的最少次数。
样例输入 Copy
4
1 1 3 2
样例输出 Copy
3
提示
让1+1+1+1 = 4,给定的数字变成4,1,3,2。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
long long a[30005] = {0};
int main()
{
ios::sync_with_stdio(false),cin.tie(NULL);
long long n;
cin>>n;
for(int i = 1; i <= n; i++)
{
cin>>a[i];
}
sort(a + 1, a + 1 + n);
long long ans = 0;
for(int i = 2; i <= n; i++)
{
if(a[i] <= a[i - 1])
{
ans = ans + (a[i - 1] - a[i] + 1);
a[i] = a[i - 1] + 1;
//啊你之前先改a[i] = a[i - 1] + 1
//再ans = ans + (a[i - 1] - a[i] + 1)
//这样ans回回加0
//不wa才怪
}
}
cout<<ans<<endl;
return 0;
}
问题 D: 小李打怪兽I
题目描述
小李对故乡的思念全部化作了对雾霾天气的怨念,这引起了掌控雾霾的邪神的极大不满,邪神派去了一只小怪兽去对付小李,由于这只怪兽拥有极高的IQ,它觉得直接消灭小李太没有难度了,它决定要和小李在智力水平上一较高下。我们可否帮助小李来战胜强大的怪兽呢?
问题是这样的:给定一堆正整数,要求你分成两堆,两堆数的和分别为S1和S2,谁分的方案使得S1*S1-S2*S2的结果小(规定S1>=S2),谁就将获得胜利。
注:S2可以等于0。
输入
第一行n(1<=n<=100),表示共有n个数
第二行共n个用空格隔开的正整数ai(ai<=100),表示给定的一堆正整数。
输出
输出就一个整数,表示 S1*S1-S2*S2 的最小值。
样例输入 Copy
4
1 2 3 4
样例输出 Copy
0
01背包 掌握不熟练
//s1 * s1 - s2 * s2 = (s1 + s2) * (s1 - s2)
//s1 + s2 常值不变 所以我们的任务是尽量减小s1 - s2
//也就是让两个集合之和的差值尽可能小
//抽象成了0-1背包 容量为sum/2 价值和重量相等
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
int dp[105][10000] = {0};
int main()
{
ios::sync_with_stdio(false),cin.tie(NULL);
int a[105] = {0};
int n,s=0;
cin>>n;
//输入每一个物品 并且计算总的值s
for(int i=1;i<=n;i++) cin>>a[i],s+=a[i];
//所有物品遍历一次
for(int i=1;i<=n;i++)
{
//对于每一个物品 拿到剩余容量为j时遇上它的最优选择
for(int j=0;j<=s/2;j++)
{
if(j>=a[i])
dp[i][j]=max(dp[i-1][j],dp[i-1][j-a[i]]+a[i]);
//只能选不拿
else
dp[i][j]=dp[i-1][j];
}
}
//dp[n][s/2]就是以s/2为起始容量 遍历完所有物品之后 能够拿到的最大物品价值
//s1 = s - s2 s2 = dp[n][s/2]
//(s - s2) * (s - s2) - s2 * s2
//(s*(s-2*dp[n][s/2]))
int s2 = dp[n][s/2];
cout<<((s - s2) * (s - s2) - s2 * s2)<<endl;
return 0;
}
问题 H: 打印图形IV
题目描述
由键盘输入任意一个自然数N,输出如下图规律的图形。
输入
只有一个整数N,为图形上半部分的行数(其中2<=N<=9)
输出
输出指定格式的图形。
样例输入 Copy
5
样例输出 Copy
5 8
4 7
3 6
2 5
1 4
0
4 1
5 2
6 3
7 4
8 5
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
//狗日的按什么规律输出不说明白也就算了 还TM用空格套路我
//人干事???
int main()
{
ios::sync_with_stdio(false),cin.tie(NULL);
int n;
cin>>n;
int a[15] = {0};
a[1] = 4;
for(int i = 2; i <= n; i++)
{
a[i] = a[i - 1] + 1;
}
for(int i = 1; i <= n; i++)
{
//先空格 再数字 再空格 再数字 再换行
for(int j = 1; j <= i - 1; j++) cout<<' ';
cout<<n - i + 1;
for(int j = 1; j <= 2*n+1-2*i; j++) cout<<' ';
cout<<a[n - i + 1]<<endl;
}
for(int i = 1; i <= n; i++) cout<<' ';
cout<<'0'<<endl;
for(int i = 1; i <= n; i++)
{
bool flag = true;
for(int j = 1; j <= n - i; j++) cout<<' ';
cout<<a[i];
for(int j = 1; j <= 2*i-1; j++)
{
if(i >= 7 && flag)
{
flag = false;
continue;
}
cout<<' ';
}
cout<<i<<endl;
}
return 0;
}
问题 K: 乐乐爱喝水
题目描述
乐乐在沙漠里走丢了。目前他有n升水,每天他会喝正整数升的水。乐乐现在想知道有多少种不同的喝法使他完全喝完这n升水。
输入
第一行包含一个正整数T(T ≤ 10),表示有T组数据。
接下来的T行,每行包含一个整数n (1≤n≤1000000),表示乐乐初始有n升水。
输出
包含T行。
每行是一个二进制数,表示能够喝完这n升水的方案数。
样例输入 Copy
2
3
6
样例输出 Copy
100
100000
提示
对于第一组数据,总共有3升水。有以下几种喝法:
a.1 1 1
b.1 2
c.2 1
d.3
总共有4种方法,4用二进制表示是100.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
//woc这尼玛都过了 果然说我还是太年轻了吗
//也别问我为什么知道一个1配n-1个0就是最终答案
//我不会推 比完赛看群里的聊天记录看来的T-T
int main()
{
ios::sync_with_stdio(false),cin.tie(NULL);
int n;
cin>>n;
int a;
while(n--)
{
cin>>a;
cout<<'1';
for(int i = 1; i < a; i++)
{
cout<<'0';
}
cout<<endl;
}
return 0;
}
问题 L: 乐乐做统计
题目描述
乐乐最近迷上了统计学,他统计了某家公司股票近n天以来每天的价格情况。为了简化问题,我们假设股价都是非负整数。但是,乐乐觉得这样的数据并不够直观,于是他灵机一动,决定将这n天的股价画成条形统计图。现在他将这个问题交给了你。
输入
包含两行。
第一行包含一个正整数n(1≤n≤100),表示乐乐统计了n天的股价情况。
第二行包含n个非负整数,数据保证不超过1000,表示每一天的股价情况。
输出
包含2*n-1列,为 n天股价的条形统计图,此处我们用*来将统计图画出。每一个条形之间隔一个空列。
第2*i-1列为对应第i天的股价情况,假设当天的股价为x,则该列应有x个*。
注意除了文末以外不能有多余空行。特殊地,第一行至少要有1个*。
样例输入 Copy
5
3 5 2 7 4
样例输出 Copy
*
*
* *
* * *
* * * *
* * * * *
* * * * *
提示
总共有5天,每天对应的股价分别是3、5、2、7、4。输出文件共有9列, 偶数列为空列,奇数列为条形,对应有3、5、2、7、4个*。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
ios::sync_with_stdio(false),cin.tie(NULL);
int n;
cin>>n;
int a[105] = {0};
int mx = 0;
for(int i = 1; i <= n; i++)
{
cin>>a[i];
if(a[i] > mx) mx = a[i];
}
for(int j = mx; j >= 1; j--)
{
for(int i = 1; i <= n; i++)
{
if(a[i] >= j)
cout<<'*';
else
cout<<' ';
if(i != n)
cout<<' ';
}
cout<<endl;
}
return 0;
}
问题 M: 乐乐做实验
题目描述
作为一个重度强迫症患者,乐乐对配平这件事有着相当强的执念。每次乐乐来到实验室,看着桌面上的天平和散落在桌面上的各式各样的物品,他就有强烈的欲望将所有东西放到天平上配平!
假设桌面上(除了天平以外)有n个物品,而且乐乐对每个物品的质量了如指掌。乐乐想知道能不能将这些物品分别放在天平两侧,使得天平平衡。对于能够配平的情况,乐乐还想知道存在多少种配平的方法。其中,天平左右放的东西交换,也视为不同的两种配平方法。但是,放置物品的顺序不同,不能视为不同的配平方法。
为了拯救这位患者,你决定挺身而出,解决这个问题。
输入
输入包含两行。
第一行包含一个正整数n(1≤n≤100),表示桌面上除了天平,有n件物品。
第二行包含n个正整数,数据保证不超过1000,表示每件物品的质量。
输出
输出包含1或2行。
第一行为Yes或No。Yes表示存在配平的方案,No表示不存在配平的方案。
如果为Yes,则还要输出第二行,为配平的方案数。
样例输入 Copy
【样例1】
5
1 2 3 4 5
【样例2】
12
728 928 246 837 19 678 538 724 763 373 850 384
样例输出 Copy
【样例1】
No
【样例2】
Yes
2
提示
5件物品的质量分别为1,2,3,4,5。质量总和为奇数,显然不存在配平的方法。
这题不会 日后再来