《看了受制了》,第二十二天,5道题,合计103道题
2023年9月20日
Acwing图论加牛客的几道题,今天这个牛客D太帅了这个思路。
牛客周赛 游游的数字圈
题目理解
就统计个数即可,0、6、8、9分别是1、1、2、1
代码实现
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
#include <set>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f3f;
ll qmi(ll a, ll b){
ll res = 1;
while(b)
{
if(b & 1) res = res * a % Mod;
a = a * a % Mod;
b >>= 1;
}
return res;
}
ll inv(ll x){ return qmi(x, Mod - 2);}
ll mo(ll x){ return (x % Mod + Mod) % Mod;}
int a[] = {1, 0, 0, 0, 0, 0, 1, 0, 2, 1};
int main() {
string s;
cin >> s;
int res = 0;
for(int i = 0; i < s.size(); i++)
res += a[(int)s[i] - 48];
cout << res;
return 0;
}
牛客周赛 竖式乘法
题目理解
用A的每一个数字去乘B得到的积求和即可。
代码实现
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
#include <set>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
ll qmi(ll a, ll b)
{
ll res = 1;
while (b)
{
if (b & 1)
res = res * a % Mod;
a = a * a % Mod;
b >>= 1;
}
return res;
}
ll inv(ll x) { return qmi(x, Mod - 2); }
ll mo(ll x) { return (x % Mod + Mod) % Mod; }
ll T, a, b;
int main()
{
cin >> T;
while(T--)
{
cin >> a >> b;
vector<ll> q;
while(b)
{
q.push_back(a * (b % 10));
b /= 10;
}
ll res = 0;
for(int i = 0 ; i < q.size(); i++)
res += q[i];
cout << res << endl;
}
return 0;
}
牛客周赛 游游的数值距离
题目理解
这个x一定是尽可能小,并且大于等于1且不等于2,然后多往后匹配一个y即可。因为阶乘太大了,根本不可能。很大.
- 切记一定是,大于等于1 且不等于2,认真读题!
- 可以多匹配一个
y
代码实现
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
#include <set>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int Mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
ll qmi(ll a, ll b)
{
ll res = 1;
while (b)
{
if (b & 1)
res = res * a % Mod;
a = a * a % Mod;
b >>= 1;
}
return res;
}
ll inv(ll x) { return qmi(x, Mod - 2); }
ll mo(ll x) { return (x % Mod + Mod) % Mod; }
ll res = 1e10, x = 1, y = 1;
ll n;
bool check(int mid, ll Q)
{
if ((Q)*mid - mid >= n)
return true;
return false;
}
int main()
{
cin >> n;
ll q = 1;
res = n;
for (int i = 2; i <= 15; i++)
{
q *= i;
if (i == 2)
continue;
ll t = n / (q - 1);
if(abs(q * t - t - n) < res && t != 2 && t >= 1)
{
res = abs(q * t - t - n);
x = i;
y = t;
}
t++;
if(abs(q * t - t - n) < res && t != 2 && t >= 1)
{
res = abs(q * t - t - n);
x = i;
y = t;
}
}
cout << x << " " << y;
return 0;
}
牛客周赛 游游的k好数组
题目理解
今天这个题,最帅的一集哦!
- 公式理解:
\[a_0 + a_1 + a_2 + ... + a_{k-1} == a_1 + a_2 + ... + a_{k-1} + a_k
\]
我们可以从以上公式推出:\(a_0 == a_k\)。即,第1组的第一个是等于第二组的第一个,那么也就继续可以推导,数组里面所有的数相等。
- 求出一组
k长度的每一个位置的最大值。可以通过以下的滚动数组来求得每一个位置上的最大值。来作为K好数组的最小值。
m[i % k] = min(m[i % k], a[i]);
- 然后我们得到位置上的最大值,就可以进行与对应的每一个数组进行做差。
- 如果差是大于
x,那么就肯定形不成k好数组 - 如果
x再形成后还有剩余。 - 那么就可以加一下,加的值是多大呢?
q / (n / k + (n % k > i)); 因为一共要给 n / k + (n % k > i)数组加和
代码实现
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
#include <set>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int Mod = 1e9 + 7, N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
ll qmi(ll a, ll b){
ll res = 1;
while(b)
{
if(b & 1) res = res * a % Mod;
a = a * a % Mod;
b >>= 1;
}
return res;
}
ll inv(ll x){ return qmi(x, Mod - 2);}
ll mo(ll x){ return (x % Mod + Mod) % Mod;}
int T;
ll n, k, q;
int main() {
scanf("%d", &T);
while(T--)
{
scanf("%lld%lld%lld", &n, &k, &q);
vector<ll> a(n);
for(int i = 0; i < n; i++)
cin >> a[i];
vector<ll> m(k);
// 找到每个位置的最大值
for(int i = 0; i < n; i++)
m[i % k] = max(m[i % k], a[i]);
ll cnt = 0;
for(int i = 0; i < n; i++)
cnt += m[i % k] - a[i];
if(cnt > q)
{
printf("-1\n");
continue;
}
ll res = 0;
q -= cnt;
for(int i = 0; i < k; i++)
{
int c = n / k + (n % k > i);
res = max(res, m[i] + q / c);
}
printf("%d\n", res);
}
return 0;
}
Acwing1128 信使
题目理解
仔细读题!仔细读题!
它会同时往所有的联通路进行走,那么到每个点都是相同的出发点,相同的出发时刻。
所以答案就是!!!最远的点!!!
图论的题一定要好好理解题意。
代码实现
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
#include <set>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int Mod = 1e9 + 7, N = 110;
const int INF = 0x3f3f3f3f;
ll qmi(ll a, ll b){
ll res = 1;
while(b)
{
if(b & 1) res = res * a % Mod;
a = a * a % Mod;
b >>= 1;
}
return res;
}
ll inv(ll x){ return qmi(x, Mod - 2);}
ll mo(ll x){ return (x % Mod + Mod) % Mod;}
int d[N], g[N][N], dist[N][N];
int n, m;
bool st[N];
bool flag[N];
int dijkstra()
{
memset(d, INF, sizeof d);
memset(st, 0, sizeof st);
d[1] = 0;
for(int i = 1; i <= n; i++)
{
int t = -1;
for(int j = 1; j <= n; j++)
if(!st[j] && (t == -1 || d[j] < d[t]))
t = j;
st[t] = true;
for(int j = 1; j <= n; j++)
d[j] = min(d[j], d[t] + g[t][j]);
}
int res = 0;
for(int i = 1; i <= n; i++)
if(d[i] > INF / 2)
return -1;
else
res = max(res, d[i]);
return res;
}
int main() {
memset(g, INF, sizeof g);
memset(dist, INF, sizeof dist);
scanf("%d%d", &n, &m);
while(m -- )
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
g[a][b] = min(g[a][b], c);
g[b][a] = min(g[b][a], c);
}
cout << dijkstra();
return 0;
}

浙公网安备 33010602011771号