7-9 抢红包(25 分)
没有人没抢过红包吧…… 这里给出N个人之间互相发红包、抢红包的记录,请你统计一下他们抢红包的收获。
输入格式:
输入第一行给出一个正整数N(≤104),即参与发红包和抢红包的总人数,则这些人从1到N编号。随后N行,第i行给出编号为i的人发红包的记录,格式如下:
KN1P1⋯NKPK
其中K(0≤K≤20)是发出去的红包个数,Ni是抢到红包的人的编号,Pi(>0)是其抢到的红包金额(以分为单位)。注意:对于同一个人发出的红包,每人最多只能抢1次,不能重复抢。
输出格式:
按照收入金额从高到低的递减顺序输出每个人的编号和收入金额(以元为单位,输出小数点后2位)。每个人的信息占一行,两数字间有1个空格。如果收入金额有并列,则按抢到红包的个数递减输出;如果还有并列,则按个人编号递增输出。
输入样例:
10
3 2 22 10 58 8 125
5 1 345 3 211 5 233 7 13 8 101
1 7 8800
2 1 1000 2 1000
2 4 250 10 320
6 5 11 9 22 8 33 7 44 10 55 4 2
1 3 8800
2 1 23 2 123
1 8 250
4 2 121 4 516 7 112 9 10
输出样例:
1 11.63
2 3.63
8 3.63
3 2.11
7 1.69
6 -1.67
9 -2.18
10 -3.26
5 -3.26
4 -12.32
这道题没什么,就是卡精度了,竟然卡精度了,不敢相信。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-8;
#define INF 100000000
typedef pair<int, int> P;
#define N 10001
const int mod = 10007;
struct node{
double money;
int num;
int id;
};
node a[N];
bool cmp(node a, node b)
{
if(abs(a.money - b.money) > eps)///这里要用eps卡一下
return a.money > b.money;
else if(a.num != b.num)
return a.num > b.num;
else
return a.id < b.id;
}
int main()
{
int n, k, c, d, cnt;
cin >> n;
for(int i = 1; i <= n; i++)
a[i].id = i, a[i].num = a[i].money = 0;
for(int i = 1; i <= n; i++)
{
cnt = 0;
scanf("%d", &k);
while(k--){
scanf("%d%d", &c, &d);
a[c].money += 0.01 * d;
cnt += d;
a[c].num += 1;
}
a[i].money -= 0.01 * cnt;
}
sort(a + 1, a + 1 + n, cmp);
for(int i = 1; i <= n; i++)
printf("%d %.2lf\n", a[i].id, a[i].money);
return 0;
}
L2-018. 多项式A除以B
这仍然是一道关于A/B的题,只不过A和B都换成了多项式。你需要计算两个多项式相除的商Q和余R,其中R的阶数必须小于B的阶数。
输入格式:
输入分两行,每行给出一个非零多项式,先给出A,再给出B。每行的格式如下:
N e[1] c[1] ... e[N] c[N]
其中N是该多项式非零项的个数,e[i]是第i个非零项的指数,c[i] 是第i个非零项的系数。各项按照指数递减的顺序给出,保证所有指数是各不相同的非负整数,所有系数是非零整数,所有整数在整型范围内。
输出格式:
分两行先后输出商和余,输出格式与输入格式相同,输出的系数保留小数点后1位。同行数字间以1个空格分隔,行首尾不得有多余空格。注意:零多项式是一个特殊多项式,对应输出为“0 0 0.0”。但非零多项式不能输出零系数(包括舍入后为0.0)的项。在样例中,余多项式其实有常数项“-1/27”,但因其舍入后为0.0,故不输出。
输入样例:4 4 1 2 -3 1 -1 0 -1 3 2 3 1 -2 0 1输出样例:
3 2 0.3 1 0.2 0 -1.0 1 1 -3.1
本来就不怎么懂多项式除法,又被样例的精度迷惑了,所以看了一个多小时都没有想出啥,然后导致二叉树的题没时间提交。Orz。
这道题卡精度是理所当然的,但是本菜鸡没怎么遇到过卡进位的题。其实就是保留0.1就卡0.05.
然后模拟还有用数组下标作为指数。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-8;
#define INF 100000000
typedef pair<int, int> P;
#define N 10000
const int mod = 10007;
double a[N], b[N], ans[N];
int main()
{
int n, m, e, ln = -1, lm = -1;
double c;
scanf("%d", &n);
for(int i = 0; i < n; i++){
scanf("%d%lf", &e, &c);
a[e] = c;
ln = max(ln, e);
}
scanf("%d", &m);
for(int i = 0; i < m; i++){
scanf("%d%lf", &e, &c);
b[e] = c;
lm = max(lm, e);
}
for(int i = ln; i >= lm; i--){
ans[i - lm] = a[i] / b[lm];
for(int j = 0; j < lm; j++){
a[i - lm + j] -= b[j] * ans[i - lm];
}
}
int nc = 0, na = 0;
for(int i = 0; i <= ln - lm; i++)
if(abs(ans[i]) >= 0.05)
nc++;
if(!nc){
puts("0 0 0.0");
}else{
printf("%d", nc);
for(int i = ln - lm; i >= 0; i--){
if(abs(ans[i]) >= 0.05)
printf(" %d %.1lf", i, ans[i]);
}
putchar('\n');
}
for(int i = 0; i < lm; i++)
if(abs(a[i]) >= 0.05)
na++;
if(!na){
puts("0 0 0.0");
}else{
printf("%d", na);
for(int i = lm - 1; i >= 0; i--){
if(abs(a[i]) >= 0.05)
printf(" %d %.1lf", i, a[i]);
}
putchar('\n');
}
return 0;
}
L2-013. 红色警报
战争中保持各个城市间的连通性非常重要。本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报。注意:若该国本来就不完全连通,是分裂的k个区域,而失去一个城市并不改变其他城市之间的连通性,则不要发出警报。
输入格式:
输入在第一行给出两个整数N(0 < N <=500)和M(<=5000),分别为城市个数(于是默认城市从0到N-1编号)和连接两城市的通路条数。随后M行,每行给出一条通路所连接的两个城市的编号,其间以1个空格分隔。在城市信息之后给出被攻占的信息,即一个正整数K和随后的K个被攻占的城市的编号。
注意:输入保证给出的被攻占的城市编号都是合法的且无重复,但并不保证给出的通路没有重复。
输出格式:
对每个被攻占的城市,如果它会改变整个国家的连通性,则输出“Red Alert: City k is lost!”,其中k是该城市的编号;否则只输出“City k is lost.”即可。如果该国失去了最后一个城市,则增加一行输出“Game Over.”。
输入样例:5 4 0 1 1 3 3 0 0 4 5 1 2 0 4 3输出样例:
City 1 is lost. City 2 is lost. Red Alert: City 0 is lost! City 4 is lost. City 3 is lost. Game Over.
数据量不大直接深搜暴力求联通量。
当一个点时要特判一下。
最后题目说要连通量为0才能输出Game Over,要加个if。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-8;
#define INF 100000000
typedef pair<int, int> P;
#define N 501
const int mod = 10007;
bool maps[N][N];
bool used[N][N];
int n, m;
int degree = 0;
void dfs(int x, int y)
{
used[x][y] = used[y][x] = true;
for(int i = 0; i < n; i++){
if(maps[x][i] && !used[x][i])
dfs(x, i);
}
for(int i = 0; i < n; i++){
if(maps[y][i] && !used[y][i])
dfs(y, i);
}
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++){
int x, y;
scanf("%d%d", &x, &y);
maps[x][y] = maps[y][x] = true;
}
for(int i = 0; i < n; i++){
maps[i][i] = true;
}
memset(used, false, sizeof used);
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++)
if(maps[i][j] && !used[i][j]){
dfs(i, j);
degree++;
}
}
int t, c, deg;
scanf("%d", &t);
while(t--){
scanf("%d", &c);
bool flag = true;
for(int i = 0; i < n; i++){
if(maps[c][i] && c != i){
flag = false;
}
maps[c][i] = maps[i][c] = false;
}
memset(used, false, sizeof used);
deg = 0;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++)
if(maps[i][j] && !used[i][j]){
dfs(i, j);
deg++;
}
}
/// printf("%d %d\n", degree, deg);
if(deg == degree || flag){
printf("City %d is lost.\n", c);
}else{
printf("Red Alert: City %d is lost!\n", c);
}
degree = deg;
}
if(degree == 0)
printf("Game Over.");
return 0;
}
7-12 最短工期(25 分)
一个项目由若干个任务组成,任务之间有先后依赖顺序。项目经理需要设置一系列里程碑,在每个里程碑节点处检查任务的完成情况,并启动后续的任务。现给定一个项目中各个任务之间的关系,请你计算出这个项目的最早完工时间。
输入格式:
首先第一行给出两个正整数:项目里程碑的数量 N(≤100)和任务总数M。这里的里程碑从 0 到 N−1 编号。随后 M 行,每行给出一项任务的描述,格式为“任务起始里程碑 任务结束里程碑 工作时长”,三个数字均为非负整数,以空格分隔。
输出格式:
如果整个项目的安排是合理可行的,在一行中输出最早完工时间;否则输出"Impossible"。
输入样例 1:
9 12
0 1 6
0 2 4
0 3 5
1 4 1
2 4 1
3 5 2
5 4 0
4 6 9
4 7 7
5 7 4
6 8 2
7 8 4
输出样例 1:
18
输入样例 2:
4 5
0 1 1
0 2 2
2 1 3
1 3 4
3 2 5
输出样例 2:
Impossible
没提交,先放上去,也找不到原题,就先这样吧
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-8;
#define INF 100000000
typedef pair<int, int> P;
#define N 100
const int mod = 10007;
int n, m, dis[N][N], ans[N], top[N];
bool mp[N][N];
bool topsort()
{
int cnt = 0;
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
{
if(!top[j]){
top[j]--;
cnt++;
if(cnt == n)
return true;
for(int k = 0; k < n; k++){
if(mp[j][k]){
ans[k] = max(ans[k], ans[j] + dis[j][k]);
top[k]--;
// mp[j][k] = 0;
}
}
}
}
//cout << top[4] << endl;
return false;
}
int main()
{
int p, q, w;
cin >> n >> m;
for(int i = 0; i < m; i++){
cin >> p >> q >> w;
mp[p][q] = true;
dis[p][q] = w;
top[q]++;
}
if(topsort()){
int mx = -1;
for(int i = 0; i < n; i++)
mx = max(mx, ans[i]);
cout << mx << endl;
}else{
cout << "Impossible\n";
}
return 0;
}