问题 A: 菱形图案
[命题人 : admin]
时间限制 : 1.000 sec 内存限制 : 128 MB
提交问题列表
解决: 1029提交量: 2680统计
题目描述
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的菱形图案。
输入
多组输入,一个整数(2~20)。
输出
针对每行输入,输出用“*”组成的菱形,每个“*”后面有一个空格。每输出一个菱形的后面需要空一行。
样例输入 Copy
2
3
4
样例输出 Copy
*
* *
* * *
* *
*
*
* *
* * *
* * * *
* * *
* *
*
*
* *
* * *
* * * *
* * * * *
* * * *
* * *
* *
*
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
while(cin >> n){
for(int i = 1;i <= n + 1;i++){
for(int j = 1;j <= n - i + 1;j++){
cout << " ";
}
for(int j = 1;j <= i;j++){
cout << "* ";
}
cout << endl;
}
for(int i = 1;i <= n;i++){
for(int j = 1;j <= i;j++){
cout << " ";
}
for(int j = 1;j <= n - i + 1;j++){
cout << "* ";
}
cout << endl;
}
cout << endl;
}
return 0;
}
问题 B: X星人的礼物
[命题人 : admin]
时间限制 : 1.000 sec 内存限制 : 128 MB
提交问题列表
解决: 324提交量: 1196统计
题目描述
他准备了很多个型号相同的礼物箱,每个礼物箱能够装礼物的最大重量都是一样的。但是X星人宝宝不希望在一个礼物箱里面装太多礼物(可能担心礼物会被压坏吧),每个礼物箱最多只允许装2个礼物。
假设X星人宝宝收到了N个礼物,现在给出每一个礼物的重量和一个礼物箱的最大装载量,请你编写一个程序计算X星人宝宝最少要用多少个礼物箱才能够把所有的礼物都装完。
输入
单组输入。
每组两行,第1行输入两个正整数,分别表示礼物的数量N和每个礼物箱的最大装载量C,其中1<=N<=1000,1<=C<=100,两者之间用英文空格隔开。
第2行输入N个不超过100的正整数,分别表示每一个礼物的重量,两两之间用英文空格隔开。
输入保证最重的礼物的重量<=C。
输出
针对所输出的数据,输出将所有的礼物全部都装完所需的礼物箱的最少个数。
样例输入 Copy
5 80
20 70 40 30 10
样例输出 Copy
3
这个就是用双指针
#include<bits/stdc++.h>
using namespace std;
bool vis[100010];
int main(){
int n,c;
while(cin >> n >> c){
vector<int>a;
for(int i = 1;i <= n;i++){
int x;
cin >> x;
a.push_back(x);
}
int ans = 0;
sort(a.begin(),a.end());
int r = n - 1,l = 0;
while(l < r){
if(a[l] + a[r] <= c){
ans++;
l++;
r--;
}else{
ans++;
r--;
}
}
if(l != r){
cout << ans << endl;
}else{
if(a[l] <= c)cout << ans + 1 << endl;
else cout << ans << endl;
}
}
return 0;
}
问题 C: 隔离14天
[命题人 : 201501010119]
时间限制 : 1.000 sec 内存限制 : 128 MB
提交问题列表
解决: 1373提交量: 2397统计
题目描述
现在假定编号为0的乘客冠状病毒核酸检验呈阳性,请编写一个程序统计需隔离的总人数(包括编号为0的乘客)。
输入
第1行的第1个数字n表示总人数,第2个数字m表示汽车数量;从第2行开始,接下来的m行表示每辆汽车的司乘人员总人数和人员编号(人员编号是一个固定值,可以对应于我们的身份证号码),每一行的第1个数字k表示该汽车的司乘人员总数,接下来的k个数字表示每一个人的编号。
输出
需要被隔离的总人数。
样例输入 Copy
2 1 2
5 10 13 11 12 14
2 0 1
2 99 2
样例输出 Copy
4
这个就是一个并查集的应用
#include<bits/stdc++.h>
using namespace std;
int a[10010],b[10010];
int main(){
int n,m;
while(cin >> n >> m){
int ans = 1;
for(int i = 0;i < m;i++){
cin >> b[i];
int c[b[i]];
for(int j = 0;j < b[i];j++){
cin >> c[j];
}
for(int j = 0;j < b[i];j++){
if(a[c[j]] == 0){
a[c[j]] = ans;
}else {
for(int k = 0;k < b[i];k++){
a[c[k]] = a[c[j]];
}
}
}
ans++;
}
ans = 0;
for(int i = 0;i < n;i++){
if(a[i] == a[0]){
ans++;
}
}
cout << ans << endl;
}
return 0;
}
问题 D: 最小生成树(Kruskal)
[命题人 : 201501010119]
时间限制 : 1.000 sec 内存限制 : 128 MB
提交问题列表
解决: 987提交量: 1922统计
题目描述
编程实现Kruskal算法,求图的最小生成树(MST)的权重。
输入
每组数据分为两个部分,第一部分为图的点数n,和边数m,
第二部分为m行,每一行输入三个数字,前两个为两个顶点的编号,第三个为边权重。
输出
最小生成树的权重。
样例输入 Copy
3 3
0 1 10
0 2 15
1 2 50
样例输出 Copy
25
#include<bits/stdc++.h>
using namespace std;
const int N = 10100;
struct node{
int a,b;
int w;
}arr[N];
int f[N];
int find(int x){
if(f[x] != x){
f[x] = find(f[x]);
}
return f[x];
}
void mer(int x1,int y1){
f[find(y1)] = find(x1);
}
bool cmp(node x,node y){
return x.w < y.w;
}
int main(){
int n,m;
while(cin >> n >> m){
int ans = 0;
int k = 0;
for(int i = 1;i <= m;i++){
cin >> arr[i].a >> arr[i].b >> arr[i].w;
}
for(int i = 1;i <= n;i++)f[i] = i;
sort(arr + 1,arr + 1 + m,cmp);
for(int i = 1;i <= m;i++){
if(find(arr[i].a) != find(arr[i].b)){
mer(arr[i].a,arr[i].b);
ans += arr[i].w;
k++;
}
if(k == n - 1){
cout << ans << endl;
break;
}
}
}
return 0;
}
问题 E: 搭建电路
[命题人 : admin]
时间限制 : 1.000 sec 内存限制 : 128 MB
提交问题列表
解决: 770提交量: 3016统计
题目描述
明明迷上了一个搭建电路的游戏。
在游戏中,每次在两个电子元件之间增加一条有效电路(两个元件之间先前没有电路相连)都将获得相应的积分奖励。
已知电子元件数量n和部分电子元件之间的奖励积分值。如何构建一个有效电路将所有元件全部连接起来,并且可以得到最多的积分奖励。
输入
每组输入数据包含m+1行。
第1行输入两个正整数n和m,其中n表示电子元件数量(n<=100),m表示提供了m对电子元件之间的奖励积分值(m<=1000)。两个正整数之间用空格隔开。
第2行到第m+1行对应m对电子元件及其对应的奖励积分值,每一行包含三个正整数,第1个和第2个整数表示电子元件编号(从1开始),第3个整数表示两个元件之间搭建电路的奖励积分num(num<1e9)。整数之间用空格隔开。
输出
每组输出占1行,输出一个正整数,即最多可以得到的积分奖励值。如果没有办法把所有元件全部连接起来,则输出“No solution.”。
样例输入 Copy
3 3
1 2 10
1 3 20
2 3 30
样例输出 Copy
50
这个就是最大生成树,注意num(num<1e9)所以要longlong
#include<bits/stdc++.h>
using namespace std;
const int N = 10100;
using ll = long long;
struct node{
ll a,b;
ll w;
}arr[N];
int f[N];
ll find(int x){
if(f[x] != x){
f[x] = find(f[x]);
}
return f[x];
}
bool mer(int x,int y){
int ans = find(x);
int res = find(y);
if(ans != res){
f[res] = ans;
return true;
}else return false;
}
bool cmp(node x,node y){
return x.w > y.w;
}
int main(){
int n,m;
while(cin >> n >> m){
ll ans = 0;
ll k = 0;
bool flag = false;
for(int i = 1;i <= m;i++){
cin >> arr[i].a >> arr[i].b >> arr[i].w;
}
for(int i = 1;i <= n;i++)f[i] = i;
sort(arr + 1,arr + 1 + m,cmp);
for(int i = 1;i <= m;i++){
if(mer(arr[i].a,arr[i].b)){
ans += arr[i].w;
}
}
int sum = 0;
for(int i = 1;i <= n;i++){
if(f[i] == i){
sum++;
if(sum >= 2){
cout << "No solution." << endl;
return 0;
}
}
}
cout << ans << endl;
}
return 0;
}
问题 F: 最小生成树(Prim)
[命题人 : 201501010119]
时间限制 : 1.000 sec 内存限制 : 128 MB
提交问题列表
解决: 1010提交量: 4987统计
题目描述
使用Prim算法求图的最小生成树(MST)
输入
每组数据分为两个部分,第一部分为图的点数n,和边数m,
第二部分为m行,每一行输入三个数字,前两个为两个顶点的编号,第三个为边权重。
输出
最小生成树,输出时按照边的两个端点的升序输出。(先看左端点,再看右端点,端点不换位置)
样例输入 Copy
3 3
0 1 10
0 2 15
1 2 50
样例输出 Copy
0 1 10
0 2 15
#include<bits/stdc++.h>
using namespace std;
const int N = 5000;
const int INF = 0x3f3f3f3f;
using ll = long long;
int a[N][N];
bool vis[N];
int n,m;
struct er{
int x,y,z;
};
er res[N];
bool cmp(er q,er w){
if(q.x != w.x)
return q.x <= w.x;
else return q.y <= w.y;
}
int flag = 0;
void prim(){
vis[0] = true;
int arr[N],sum[N];
for(int i = 0;i < n;i++){
arr[i] = fabs(a[0][i]);
sum[i] = 0;
}
for(int i = 1;i < n;i++){
int j = 0;
for(int k = 0;k < n;k++){
if(!vis[k] && arr[k] < arr[j]){
j = k;
}
}
if(a[sum[j]][j] > 0){
res[flag].x = sum[j];
res[flag].y = j;
res[flag].z = arr[j];
flag++;
}
else {
res[flag].x = j;
res[flag].y = sum[j];
res[flag].z = arr[j];
flag++;
}
vis[j] = true;
for(int i = 0;i < n;i++){
if(!vis[i] && (a[j][i] < arr[i])){
arr[i] = fabs(a[j][i]);
sum[i] = j;
}
}
}
}
int main(){
while(cin >> n >> m){
flag = 0;
int x,y,z;
memset(a,INF,sizeof(a));
memset(vis,false,sizeof vis);
for(int i = 0;i < m;i++){
cin >> x >> y >> z;
a[x][y] = z;
a[y][x] = -1 * z;
}
prim();
sort(res,res + flag,cmp);
for(int i = 0;i < flag ;i++){
cout << res[i].x << " " << res[i].y << " " << res[i].z << endl;
}
}
return 0;
}
问题 G: 台球碰撞
[命题人 : 外部导入]
时间限制 : 1.000 sec 内存限制 : 128 MB
提交问题列表
解决: 28提交量: 87统计
题目描述
在平面直角坐标系下,台球桌是一个左下角在(0,0),右上角在(L,W)的矩形。有一个球心在(x,y),半径为R的圆形母球放在台球桌上(整个球都在台球桌内)。受撞击后,球沿极角为a的射线(即:x正半轴逆时针旋转到此射线的角度为a)飞出,每次碰到球桌时均发生完全弹性碰撞(球的速率不变,反射角等于入射角)。
如果球的速率为v,s个时间单位之后球心在什么地方?
输入
输入文件最多包含25组测试数据,每个数据仅一行,包含8个正整数L,W,x,y,R,a,v,s(100<=L,W<=105,1<=R<=5, R<=x<=L-R, R<=y<=W-R, 0<=a<360, 1<=v,s<=105),含义见题目描述。L=W=x=y=R=a=v=s=0表示输入结束,你的程序不应当处理这一行。
输出
对于每组数据,输出仅一行,包含两个实数x, y,表明球心坐标为(x,y)。x和y应四舍五入保留两位小数。
样例输入 Copy
100 100 80 10 5 90 2 23
110 100 70 10 5 180 1 9999
0 0 0 0 0 0 0 0
样例输出 Copy
80.00 56.00
71.00 10.00
这个就是一个几何的水题,不用想的太复杂了
#include<bits/stdc++.h>
using namespace std;
int main(){
int l,w,r,a,v,s;
int t;
double vx,vy,x,y;
double pi = acos(-1.0);
while( cin>>l>>w>>x>>y>>r>>a>>v>>s )
{
if( l==0 ) break;
vy=sin( a*pi/180 )*v;
vx=cos( a*pi/180 )*v;
t=0;
while( t!=s )
{
x+=vx;
y+=vy;
while( (x-r<0) || (x+r>l) || (y-r<0) || (y+r>w) )
{
if( x-r<0 ) x=2*r-x, vx=-vx;
if( x+r>l ) x=2*l-2*r-x, vx=-vx;
if( y-r<0 ) y=2*r-y, vy =-vy;
if( y+r>w ) y=2*w-2*r-y, vy =-vy;
}
t++;
}
cout << fixed << setprecision(2) << x << " " << y << endl;
}
return 0;
}