[20181025上午][模拟赛]
T1
思路
直接模拟每一秒发生的变化并且用优先队列优化一下,可以拿到80分。然后发现中间一些时间什么事情都没有干。所以可以直接跳过那些无贡献的时间。时间复杂度为\(O(mlogn)\)
代码
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#define pi pair<int,int>
using namespace std;
const int N = 100000 + 100;
typedef long long ll;
ll read() {
ll x = 0, f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
int n ,m ,x;
int ans2;
int a[N];
priority_queue<pi,vector<pi>,greater<pi> > q;
int main() {
freopen("fish.in","r",stdin);
freopen("fish.out","w",stdout);
int m = read(),n = read(),x = read();//m是鱼的数量,x是时间,n是猫
for(int i = 1;i <= n;++i) {
int x = read();
q.push(make_pair(x,x));
m--;
}
int now = 1;
for(;now < x&&m;++now) {
while(!q.empty()) {
pi k = q.top();
if(k.first > now) {
now = k.first - 1;
break;
}
q.pop();
q.push(make_pair(k.second+now,k.second));
m--;
if(!m) break;
}
}
while(!q.empty()) ans2 += q.top().first > x,q.pop();
cout<<m<<" "<<ans2;
return 0;
}
T2
思路
先去写了一个背包,然后过了小样例,没过大样例。然后觉着肯定要排序,试了五六种排序方法,过了大样例。
代码
/*f[i][j]表示前i个物品剩余j的钱所能得到的最大价值
if(j + p[i] >= q[i])
f[i][j] = max(f[i - 1][j + p[i]] + v[i],f[i - 1][j])
else f[i][j] = f[i - 1][j]
*/
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const int N = 1000 + 100,M = 5000 + 100;
ll read() {
ll x = 0, f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
ll f[N][M];
int n ,m;
struct node{
int p,q;
ll v;
}a[N];
bool cmp(node x,node y) {
return x.q - x.p > y.q - y.p;
}
void solve() {
for(int i = 1;i <= n;++i) {
for(int j = 0;j <= m;++j) {
if(j + a[i].p > m || j + a[i].p < a[i].q) {
f[i][j] = f[i - 1][j];
continue;
}
f[i][j] = max(f[i-1][j],f[i-1][j + a[i].p] + a[i].v);
}
}
ll ans = 0;
for(int i = 0;i <= m;++i)
ans = max(ans,f[n][i]);
cout<<ans;
}
void solve1() {
for(int i = 1;i <= n;++i) {
for(int j = 0 ;j <= m;++j) {
if(j > a[i].p)
f[i][j] = max(f[i-1][j - a[i].p] + a[i].v , f[i-1][j]);
else f[i][j] = f[i-1][j];
}
}
ll ans = 0;
for(int i = 0;i <= m;++i) ans = max(ans,f[n][i]);
cout<<ans;
}
int main() {
freopen("bag.in","r",stdin);
freopen("bag.out","w",stdout);
n = read(),m = read();
int bz1 = 0;
for(int i = 1;i <= n;++i) {
a[i].p = read();a[i].q = read();a[i].v = read();
if(a[i].p != a[i].q) bz1 = 1;
}
if(!bz1) {
solve1();
return 0;
}
sort(a + 1,a + n + 1,cmp);
solve();
return 0;
}
T3
思路
对于前70分,直接模拟就行了。将走过的位置标记一下,然后从外部bfs一遍。标记过的点不入队。bfs不到的点就是答案了。剩下的三十分离散化一下。似乎很麻烦,留个坑吧
70分代码
#include<cstdio>
#include<iostream>
#include<queue>
#define pi pair<int,int>
using namespace std;
const int N = 2018;
typedef long long ll;
int dx[5] = {0,1,-1,0,0};
int dy[5] = {0,0,0,1,-1};
ll read() {
ll x = 0, f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
int a[N + 10][N + 10];
int X,Y;
queue<pi>q;
int bfs() {
int ans = 0;
q.push(make_pair(1,1));
ans++;
a[1][1] = 1;
while(!q.empty()) {
int x = q.front().first,y = q.front().second;
q.pop();
for(int i = 1;i <= 4;++i) {
int x_ = x + dx[i],y_ = y + dy[i];
if(!a[x_][y_] && x_ <= 2018 && x_ >= 1 && y_ <= 2018 && y_ >= 1) {
ans++;
a[x_][y_] = 1;
q.push(make_pair(x_,y_));
}
}
}
return ans;
}
int main() {
freopen("beng.in","r",stdin);
freopen("beng.out","w",stdout);
int k = read();
X = 1005,Y = 1005;
char c;
int b;
a[X][Y] = 1;
while(k--) {
cin>>c;b = read();
if(c == 'U') {
int To = X - b;
while(X >To) {
X--;
a[X][Y] = 1;
}
}
if(c == 'D') {
int To = X + b;
while(X < To) {
X++;
a[X][Y] = 1;
}
}
if(c == 'L') {
int To = Y - b;
while(Y > To) {
Y--;
a[X][Y] = 1;
}
}
if(c == 'R') {
int To = Y + b;
while(Y < To) {
Y++;
a[X][Y] = 1;
}
}
}
cout<<N * N - bfs();
return 0;
}
总结
期望得分:100 + 100 + 0 = 200
实际得分:100 + 100 + 0 = 200
t3的70分没拿实在可惜。前两题还可以。t1第一次写的时候bug较多。
一言
好几次张口却发现,想说的那么多,能说的却那么少,况且这世界也已经够吵。 ——这世界已经够吵了