问题 A: 分书问题
时间限制: 1 Sec 内存限制: 128 MB
[提交] [状态]题目描述
已知有n本书(从1~n编号)和n个人(从1~n编号),每个人都有一个自己喜爱的书的列表,现在请你编写一个程序,设计一种分书方案,使得每个人都能获得一本书,且这本书一定要在他的喜爱列表中。
输入
输入数据共若干行,第一行为一个正整数n(n <= 20),从第2行到第n+1行,每行有n个0或1组成,第k行表示编号为k-1的人对这n本书的喜好列表,0表示不喜欢,1表示喜欢。
输出
输出数据仅一个整数,表示符合条件的分配方案的总数。
样例输入 Copy
5 00110 11001 01100 00010 01001样例输出 Copy
1
#include<bits/stdc++.h>
typedef unsigned long long ULL;
using namespace std;
typedef long long ll;
typedef pair<int,int>pp;
const int N=200010;
vector<int>v;
#define X first
#define Y second
priority_queue<int>q;
int vis[25],cnt,n;
char str[25][25];
void dfs(int k)
{
if(k==n)
{
int f=1;
for(int i=1;i<=n;i++)
if(vis[i]==0){f=0;break;}
if(f==1) cnt++;
}
for(int i=1;i<=n;i++)
{
if(str[i][k]=='1'&&vis[i]==0)
vis[i]=1,dfs(k+1),vis[i]=0;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",str[i]);
}
dfs(0);
printf("%d",cnt);
return 0;
}
/**************************************************************
Problem: 15301
User: 2019UPC110
Language: C++
Result: 正确
Time:229 ms
Memory:2028 kb
****************************************************************/
问题 C: 排队出发
时间限制: 1 Sec 内存限制: 128 MB
[提交] [状态]题目描述
神牛岛是传说中的一个岛屿,凡是成功到那里游历,完成探险并返回的人,都会成为神牛。但是,现实中却没有人知道如何到达神牛岛。
这天夜里,笃志者睡着之后,不久就进入了梦乡。他突然看到有人在问,“有人想去神牛岛的吗?”神牛岛之旅的牌子前,就开始有不少勇士报名要去冒险探索。
“我们会把勇士安排在前,带领大家一起去神牛岛。下面开始点名!”管理队伍的 LXY 神牛说。其实说实话,给学生排队这种工作是最让神牛头疼的了。因为同学们都有自尊心,都不愿意排后面。共有 n 个同学要排成一列,每个同学有两个属性:影响力和承受能力。给一个同学造成的心理创伤指数等于所有在他前面同学的影响力之和减去他的承受能力。现在请你帮忙安排一下点名顺序,尽量使受到心理创伤最大的同学少受创伤。输入
输入包含n+1行:
第1行是整数n,表示同学的个数。
第2~n+1行每行两个自然数,分别是该同学的影响力和承受能力。输出
输出包含1行,为你安排的顺序中受到心理创伤最大的同学受到的创伤。
样例输入 Copy
3 10 3 2 5 3 3样例输出 Copy
2提示
对于100%的数据,1<=n<=50000,1<=影响力<=10000,1<=承受能力<=1,000,000,000。
https://www.cnblogs.com/ZERO-/p/9347296.html
#include<bits/stdc++.h>
typedef unsigned long long ULL;
using namespace std;
typedef long long ll;
typedef pair<int,int>pp;
const int N=200010;
vector<int>v;
#define X first
#define Y second
priority_queue<int>q;
const int maxn =50050,INF=1e9+1;
ll sum,cnt,n;
struct node{
ll a,b;
}nd[50005];
bool cmp(node x,node y)
{
return x.a+x.b<y.a+y.b;
}
int main()
{
scanf("%lld",&n);
ll ans=-INF;
for(int i=1;i<=n;i++)
scanf("%lld%lld",&nd[i].a,&nd[i].b);
sort(nd+1,nd+1+n,cmp);
for(int i=1;i<=n;i++)
{
ans=max(ans,sum-nd[i].b);
sum+=nd[i].a;
}
printf("%lld",ans);
return 0;
}
/**************************************************************
Problem: 15303
User: 2019UPC110
Language: C++
Result: 正确
Time:34 ms
Memory:2812 kb
****************************************************************/
#include<bits/stdc++.h>
typedef unsigned long long ULL;
using namespace std;
typedef long long ll;
typedef pair<int,int>pp;
const int N=200010;
vector<int>v;
#define X first
#define Y second
priority_queue<int>q;
const int maxn =50050,INF=1e9+1;
ll sum,cnt,n;
struct node{
ll a,b;
}nd[50005];
bool cmp(node x,node y)
{
if (x.a==y.a) return x.b<y.b;
return x.a<y.b;
}
int main()
{
scanf("%lld",&n);
ll ans=-INF;
for(int i=1;i<=n;i++)
scanf("%lld%lld",&nd[i].a,&nd[i].b);
sort(nd+1,nd+1+n,cmp);
for(int i=1;i<=n;i++)
{
ans=max(ans,sum-nd[i].b);
sum+=nd[i].a;
}
printf("%lld",ans);
return 0;
}
/**************************************************************
Problem: 15303
User: 2019UPC110
Language: C++
Result: 时间超限
****************************************************************/
问题 B: 青铜莲花池
时间限制: 1 Sec 内存限制: 128 MB
[提交] [状态]
题目描述
为了让奶牛们娱乐和锻炼,农夫约翰建造了一个美丽的池塘。这个长方形的池子被分成了M行N列个方格(1 ≤ M, N ≤ 30)。一些格子是坚固得令人惊讶的莲花,还有一些格子是岩石,其余的只是美丽、纯净、湛蓝的水。
贝西正在练习芭蕾舞,她站在一朵莲花上,想跳到另一朵莲花上去,她只能从一朵莲花跳到另一朵莲花上,既不能跳到水里,也不能跳到岩石上。
贝西的舞步很像象棋中的马步:每次总是先横向移动M1 (1 ≤ M1 ≤ 30)格,再纵向移动M2 (1 ≤ M2 ≤ 30, M1 M2)格,或先纵向移动M1格,再横向移动M2格。最多时,贝西会有八个移动方向可供选择。
给定池塘的布局和贝西的跳跃长度,请计算贝西从起点出发,到达目的地的最小步数,我们保证输入数据中的目的地一定是可达的。
输入
第一行:四个用空格分开的整数:M,N,M1和M2
第二行到M + 1行:第i + 1行有N个用空格分开的整数,描述了池塘第i行的状态:0 为水,1 为莲花,2 为岩石,3 为贝西所在的起点,4 为贝西想去的终点。
输出
一个整数,表示从起点到终点的最少步数
样例输入 Copy
4 5 1 2 1 0 1 0 1 3 0 2 0 4 0 1 2 0 0 0 0 0 1 0
样例输出 Copy
2
提示
贝西从第二行的最左边出发,目标是第二行的最右边。贝西先跳到第一行第三列的莲花上,再跳到终点,需要两步。
#include<bits/stdc++.h>
typedef unsigned long long ULL;
using namespace std;
typedef long long ll;
typedef pair<int,int>pp;
const int N=2010;
vector<int>v;
#define X first
#define Y second
int n, m, x, y, r, c, sx, sy;
struct node
{
int x, y, dis;
};
queue<node> q;
int a[N][N], xx[8], yy[8];
int main(void)
{
scanf("%d%d%d%d", &n, &m, &x, &y);
for (int i = 1; i <= n; ++i) // 输入
{
for (int j = 1; j <= m; ++j)
{
scanf("%d", &a[i][j]);
if (a[i][j] == 3) sx = i,sy = j;
}
}
xx[0] = -y;
yy[0] = -x;
xx[1] = x;
yy[1] = y;
xx[2] = x;
yy[2] = -y;
xx[3] = -x;
yy[3] = y;
xx[4] = -x;
yy[4] = -y;
xx[5] = y;
yy[5] = x;
xx[6] = y;
yy[6] = -x;
xx[7] = -y;
yy[7] = x;
q.push({sx, sy, 0});
while (!q.empty())
{
x = q.front().x;
y = q.front().y;
for (int i = 0; i < 8; ++i)
{
r = x + xx[i];
c = y + yy[i];
if (a[r][c] == 4)
{
printf("%d", q.front().dis + 1); // 到达终点,输出步数
return 0;
}
if (a[r][c] == 1)
{
a[r][c] = 0;
q.push({r, c, q.front().dis + 1});
}
}
q.pop();
}
return 0;
}
/**************************************************************
Problem: 15302
User: 2019UPC110
Language: C++
Result: 正确
Time:1 ms
Memory:17812 kb
****************************************************************/