2023牛客算法基础训练营补题4
M
solve
直接构建1 1 3 1 1 3....的序列即可
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 1e5 + 5;
int f[N];
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
for(int i = 1; i <= 1e5; i++){
if(i % 3 == 0) f[i] = 3;
else f[i] = 1;
}
int n;
cin >> n;
for(int i = 1; i <= n; i++){
cout << f[i] << " \n"[i == n];
}
return 0;
}
//题目所考察知识:
//心得体会:
A
solve
比较 \(x^{y}\) 和 \(y^{x}\) 之间的大小,直接取log即可
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
int scal(int x,int y,int z){
int res = 0;
while(x--){
res += y;
y *= z;
}
return res;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int x,y;
cin >> x >> y;
double p1 = (double)y * log2(x);
double p2 = (double)x * log2(y);
// cout << 1e-6 << endl;
if(abs(p1 - p2) <= 1e-6) cout << min(x,y) << endl;
else if(p1 > p2) cout << x << endl;
else if(p1 < p2) cout << y << endl;
return 0;
}
//题目所考察知识:
//心得体会:
L
solve
实际上判断能否构成三角形只需要判断最小的两条边是否能大于第三边即可
根据题目中所给的三个未知数三个方程可以求出la或lb或lc
根据方程解未知数即可
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
int l[5];
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
void solve(){
int va,vb,vc;
cin >> va >> vb >> vc;
l[1] = vc - va + vb;
if(l[1] % 2 == 1) {
cout << "No" << endl;
return;
}
l[1] /= 2;
l[2] = vc - l[1];
l[3] = va - l[2];
int la = l[1];
int lb = l[2];
int lc = l[3];
sort(l+1,l+4);
if(l[1] > 0 && l[2] > 0 && l[3] > 0){
if(l[1] + l[2] > l[3]) cout << "Yes" << endl,cout << la << " " << lb << " " << lc << endl;
else cout << "No" << endl;
}
else cout << "No" << endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--){
solve();
}
return 0;
}
//题目所考察知识:
//心得体会:
E
solve
直接模拟即可,要注意相邻的两次攻击之间有间隔时间
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 1e5 + 5;
int h[N],v[N];
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n,t,a;
cin >> n >> t >> a;
for(int i = 1; i <= n; i++) cin >> h[i] >> v[i];
int res = 0;
int flag = 0;
for(int i = 1; i <= n; i++){
if(h[i] <= a) {
res += 1;
if(i != n)
res += (t-1);
}
else{
h[i] -= a;
res += 1;
int x = t * v[i] - a;
if(x >= 0) {
cout << "-1" << endl;
flag = 1;
break;
}
else{
x = -x;
int p = h[i] % x == 0 ? h[i]/x:(h[i]/x+1);
res += t*p;
if(i != n)
res += (t-1);
}
}
}
if(!flag) cout << res << endl;
// cout << (1 == 2 ? 1:2/2+1) << endl;
return 0;
}
//题目所考察知识:
//心得体会:
C
solve
该题当时想复杂了,最后答案直接用 \(dp[m]-dp[m-w[i]]-v[i]+1\) 即可
把每个物品单独领出来考虑,时间复杂度 \(O(n^{2} \times m)\)
赛时代码
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 105;
int dp[N];
int vis[N][N];
int w[N],v[N];
int s[N];
int dpt[105][105];
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n,m;
cin >> n >> m;
for(int i = 1; i <= n; i++) cin >> w[i] >> v[i];
for(int i = 1; i <= n; i++) {
for(int j = m; j >= w[i]; j--){
if(dp[j] < dp[j-w[i]]+v[i]) {
dp[j] = dp[j-w[i]] + v[i];
for(int k = 1; k <= n; k++)
{vis[j][k] = vis[j-w[i]][k];
}
vis[j][i] = 1;
}
else if(dp[j] == dp[j-w[i]]+v[i]){
for(int k = 1; k <= n; k++)
{vis[j][k] &= vis[j-w[i]][k],vis[j][i] &= 1;
}
}
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
if(j == i) continue;
for(int k = m-w[i]; k >= w[j]; k--){
dpt[k][i] = max(dpt[k][i],dpt[k-w[j]][i]+v[j]);
}
}
s[i] = dpt[m-w[i]][i] + v[i];
}
for(int i = 1; i <= n; i++){
if(s[i] < dp[m]) {
cout << dp[m] - s[i] + 1 << endl;
}
else if(s[i] == dp[m]){
if(vis[m][i]) cout << 0 << endl;
else{
cout << 1 << endl;
}
}
}
return 0;
}
//题目所考察知识:
//心得体会:
B
solve
实际上也是列方程解未知数的问题,但是要注意很多细节
主要是要把几个方程全部找全
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 1e5 + 5;
int c[N];
int a[N];
int b[N];
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n,m;
cin >> n >> m;
for(int i = 1; i <= n; i++)
cin >> c[i];
int flag = 0;
if(n % 2 == 0){
for(int i = 1; i <= n/2; i++){
int p = c[i] + c[n+1-i] - m;
if(c[i] == c[n+1-i]) {
a[i] = c[i];
b[i] = 0;
continue;
}
if((c[i]+c[n+1-i])%2 == 0) {
a[i] = (c[i]+c[n+1-i])/2;
b[i] = c[i] + m - a[i];
continue;
}
if((c[i]+c[n+1-i]+m)%2 == 0) {
a[i] = (c[i]+c[n+1-i]+m)/2;
b[i] = c[i] + m - a[i];
continue;
}
if(p % 2 == 1 || p % 2 == -1) {
cout << "No" << endl;
flag = 1;
break;
}
else{
a[i] = p / 2;
b[i] = c[i] - a[i];
}
}
if(!flag){
cout << "Yes" << endl;
for(int i = 1; i <= n/2; i++){
if(a[i] < 0){
a[i] %= m;
a[i] += m;
}
else if(a[i] >= m) a[i] %= m;
if(b[i] < 0){
b[i] %= m;
b[i] += m;
}
else if(b[i] >= m) b[i] %= m;
}
for(int j = n/2+1; j <= n; j++){
a[j] = a[n+1-j];
b[j] = b[n+1-j] == 0 ? 0:(m - b[n+1-j]);
}
for(int i = 1; i <= n; i++)
cout << a[i] << " \n"[i == n];
for(int i = 1; i <= n; i++)
cout << b[i] << " \n"[i == n];
}
}
else{
for(int i = 1; i <= n/2; i++){
int p = c[i] + c[n+1-i] - m;
if(c[i] == c[n+1-i]) {
a[i] = c[i];
b[i] = 0;
continue;
}
if((c[i]+c[n+1-i])%2 == 0) {
a[i] = (c[i]+c[n+1-i])/2;
b[i] = c[i] + m - a[i];
continue;
}
if((c[i]+c[n+1-i]+m)%2 == 0) {
a[i] = (c[i]+c[n+1-i]+m)/2;
b[i] = c[i] + m - a[i];
continue;
}
// cout << p << endl;
if(p % 2 == 1 || p % 2 == -1) {
cout << "No" << endl;
flag = 1;
break;
}
else{
a[i] = p / 2;
b[i] = c[i] - a[i];
}
}
if(!flag){
cout << "Yes" << endl;
for(int i = 1; i <= n/2; i++){
if(a[i] < 0){
a[i] %= m;
a[i] += m;
}
else if(a[i] >= m) a[i] %= m;
if(b[i] < 0){
b[i] %= m;
b[i] += m;
}
else if(b[i] >= m) b[i] %= m;
}
b[n/2+1] = 0;
a[n/2+1] = c[n/2+1];
int x = n/2+1;
if(a[x] < 0) {
a[x] %= m;
a[x] += m;
}
else if(a[x] >= m) a[x] %= m;
for(int j = n/2+2; j <= n; j++){
a[j] = a[n+1-j];
b[j] = b[n+1-j] == 0 ? 0:(m - b[n+1-j]);
}
for(int i = 1; i <= n; i++)
cout << a[i] << " \n"[i == n];
for(int i = 1; i <= n; i++)
cout << b[i] << " \n"[i == n];
}
}
return 0;
}
//题目所考察知识:
//心得体会:
D
solve
二分+dfs+dp
时间复杂度为 \(O(log_{2}n \times n \times m)\)
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 5005;
int w[N], v[N];
int dp[N];
int res[N];
int ans;
int n, m;
void dfs(int l, int r, vector<int> vec) {
if (l == r) {
int p = vec[m];
int q = vec[m - w[l]];
if (p == ans) {
res[l] = p - q - v[l] + 1;
} else
res[l] = 0;
return;
}
int mid = l + r >> 1;
vector<int> f = vec;
for (int i = l; i <= mid; i++) {
for (int j = m; j >= w[i]; j--)
f[j] = max(f[j], f[j - w[i]] + v[i]);
}
dfs(mid + 1, r, f);
f = vec;
for (int i = mid + 1; i <= r; i++) {
for (int j = m; j >= w[i]; j--)
f[j] = max(f[j], f[j - w[i]] + v[i]);
}
dfs(l, mid, f);
}
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void print(int x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
print(x / 10);
putchar(x % 10 + '0');
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
vector<int> butful(m + 5);
for (int i = 1; i <= n; i++)
cin >> w[i] >> v[i];
for (int i = 1; i <= n; i++) {
for (int j = m; j >= w[i]; j--)
dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
}
ans = dp[m];
dfs(1, n, butful);
for (int i = 1; i <= n; i++)
cout << res[i] << endl;
return 0;
}
// 题目所考察知识:
// 心得体会:
F
solve
树的遍历
// ξ†(ᗜ ˰ ᗜ)†ξ
// 去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
int l, m, r;
int x;
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void print(int x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
print(x / 10);
putchar(x % 10 + '0');
}
void f1(int u, int deep) {
l++;
if (u == x)
return;
if (u > x)
f1(u - ((int)1 << deep), deep - 1);
else {
l += (int)1 << (deep + 1);
l--;
f1(u + ((int)1 << deep), deep - 1);
}
};
void f2(int u, int deep) {
if (u == x) {
r += ((int)1 << deep + 1) - 1;
return;
}
if (u > x)
f2(u - ((int)1 << deep - 1), deep - 1);
else {
r += ((int)1 << deep) - 1;
f2(u + ((int)1 << deep - 1), deep - 1);
}
};
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
int k, q;
cin >> k >> q;
int n = (int)1 << k;
while (q--) {
l = r = m = 0;
cin >> x;
m = x;
int d;
for (d = 0; d <= 60; d++) {
if (x & ((int)1 << d))
break;
}
f1(n, k - 1);
f2(n, k);
if (x == n)
r = r + (int)1 >> (int)1;
cout << l << " " << m << " " << r << endl;
}
return 0;
}
J
solve
dfs+建图
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e3 + 10, M = 1e5 + 10;
int n, m, vis[2][N], ans[N];
struct Edge {
int nxt, to;
} E1[M << 1], E2[M << 1];
int H1[N], T1, H2[N], T2;
inline int read() {
int s = 0, w = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
w = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
s = s * 10 + ch - '0';
ch = getchar();
}
return s * w;
}
inline void add(int x, int y) {
E1[++T1].to = y;
E1[T1].nxt = H1[x];
H1[x] = T1;
E2[++T2].to = x;
E2[T2].nxt = H2[y];
H2[y] = T2;
}
inline void dfs1(int u) {
for (int i = H1[u]; i; i = E1[i].nxt) {
int v = E1[i].to;
if (!vis[0][v]) {
vis[0][v] = 1;
dfs1(v);
}
}
}
inline void dfs2(int u) {
for (int i = H2[u]; i; i = E2[i].nxt) {
int v = E2[i].to;
if (!vis[1][v]) {
vis[1][v] = 1;
dfs2(v);
}
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++)
ans[i] = -1;
for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
add(u, v);
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++)
vis[0][j] = vis[1][j] = 0;
dfs1(i);
dfs2(i);
int res1 = 0, res2 = 0;
for (int j = 1; j <= n; j++) {
res1 += vis[0][j];
res2 += vis[1][j];
}
if (res1 + res2 == n - 1)
ans[res2 + 1] = i;
}
for (int i = 1; i <= n; i++)
cout << ans[i] << " \n"[i == n];
return 0;
}