A.Nastya and Rice
题意:
给定个物品,每个物品的重量都限制在
,询问是否存在一种方案使得这
个物品的重量合在
之间
题解:
极限情况判断大小,比较和
与
和
即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 2e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
void solve()
{
int n, a, b, c, d;
scanf("%d%d%d%d%d", &n, &a, &b, &c, &d);
if (n * (a + b) < c - d || n * (a - b) > c + d)
puts("No");
else
puts("Yes");
}
int main()
{
int t;
for (scanf("%d", &t); t >= 1; t--)
solve();
} B.Nastya and Door
题意:
给定个点
和一条长度为
的线段,要求区间内的极大值点(峰点)尽可能多。
题解:
统计所有极大值点之后扫描一遍。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 2e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int a[maxn];
bool check[maxn];
void solve()
{
int n, k;
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
check[1] = check[n] = false;
for (int i = 2; i < n; i++)
check[i] = (a[i] > a[i - 1]) && (a[i] > a[i + 1]);
int sum = 0;
for (int i = 1; i < k; i++)
sum += check[i];
int ans = -1, l = 0;
for (int i = k; i <= n; i++)
{
if (check[i - k + 1])
sum--;
if (ans < sum)
{
ans = sum;
l = i - k + 1;
}
sum += check[i];
}
printf("%d %d\n", ans + 1, l);
}
int main()
{
int t;
for (scanf("%d", &t); t >= 1; t--)
solve();
} C.Nastya and Strange Generator
题意:
有一个生成器,会按照以下条件从到
从小到大每次赋一个值构造序列:
- 规定
为最小的大于等于
的且未被赋值的下标。
- 规定
为
中
的个数。
- 选取任意一个
值进行赋值。
现在给出一个序列,问是否可以通过这个生成器生成。
题解:
注意到初始状态下所有的都是自己,所以所有的
都为
。但是每确定一个数字后,当前确定的下标的
就会增加。所以在一个数字确定后,接下来的数字一定是连续到串结束或者已被赋值的点。根据第一个数字的下标不断进行扫描即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 1e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int p[maxn], idx[maxn];
bool vis[maxn];
void solve()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &p[i]);
idx[p[i]] = i;
vis[i] = false;
}
for (int i = 1; i <= n; i++)
if (!vis[i])
for (int j = idx[i]; j <= n; j++)
{
if (vis[p[j]])
break;
if (p[j] - j == i - idx[i])
vis[p[j]] = true;
else
{
puts("No");
return;
}
}
puts("Yes");
}
int main()
{
int t;
for (scanf("%d", &t); t >= 1; t--)
solve();
} D.Nastya and Scoreboard
题意:
给定个记分板,每个记分板由
根火柴棒组成(
为
表示不亮,
为
表示亮),最终结果为各位上上亮的部分,问加
根火柴棒以后能拼出的最大数字。
题解:
首先可以肯定优先将高位变成最大的肯定比变低位来的优,因此将每一位的状态用二进制的形式表示,从最高位依次dfs暴力搜一遍能到达的最大值即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
const int maxn = 3e3 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
int tab[10] = {119, 18, 93, 91, 58, 107, 111, 82, 127, 123};
int n, k, a[maxn], ans[maxn];
bool vis[maxn][maxn];
string s;
void dfs(int i, int x)
{
if (x > k || vis[i][x])
return;
vis[i][x] = 1;
if (i == n)
{
if (x == k)
{
for (int j = 0; j < n; j++)
printf("%d", ans[j]);
exit(0);
}
return;
}
for (int j = 9; j >= 0; j--)
{
ans[i] = j;
if ((tab[j] & a[i]) == a[i])
dfs(i + 1, x + __builtin_popcount(tab[j] ^ a[i]));
}
}
int main()
{
scanf("%d%d",&n,&k);
for (int i = 0; i < n; i++)
{
cin >> s;
for (char j : s)
a[i] = a[i] * 2 + (j - '0');
}
dfs(0, 0);
puts("-1");
return 0;
} 
京公网安备 11010502036488号