ACM日常训练日记——7.31(牛客萌新第三场)
1.ACM日常训练日记——7.31(牛客萌新第三场)
2.ACM日常训练日记——7.29(单调栈,滑动窗口,线性dp)3.ACM日常训练日记——7.26(线性dp+cf div2)4.ACM日常训练日记——8.1(区间dp)5.ACM日常训练日记——7.30(并查集)6.ACM日常训练日记——7.237.ACM日常训练日记——7.248.ACM日常训练日记——7.25(背包dp,最长公共子序列)记忆化搜素+细节二分9.周总结10.SMU Summer 2024 Contest Round 3(7.10)zhaosang(二进制暴力)11.周总结(还需要再认真看学习比如Strange Balls,预处理)12.ACM日常训练日记——8.213.ACM日常训练日记——8.8(二分dp,最小生成树+克鲁斯卡尔算法和普利姆算法)14.8.12(打表+位运算+思维)15.8.13(优先队列贪心维护+打表找规律+对顶堆优先队列+DFS减枝+贪心dp)16.8.14 (河南牛客萌新赛 线段树 ,ST求区间最值,迪杰斯特拉建正反图,bfs+二分,模拟)+状态bfs搜素17.9.11 codeforces18.题解9.29-10.3- nowcoder训练
- 正则表达式
签到
- 正则表达式
#include<bits/stdc++.h>
using namespace std;
int main(){
long long n;
long long ans=0;
cin>>n;
while(n--){
long long a,b,c,d;
scanf("%lld.%lld.%lld.%lld",&a,&b,&c,&d);
if((a<=255)&&(b<=255)&&(c<=255)&&(d<=255)){
ans++;
}
}
cout<<ans;
}
- SSH
简单的字符串模拟
#include <bits/stdc++.h>
using namespace std;
using ll =long long;
// 2024.7.31:14:01
struct User {
string name;
vector<string> publicKeys;
};
struct Host {
string ip;
vector<User> users;
};
int main() {
int m, n, q;
cin >> m >> n >> q;
//存密钥
unordered_map<string, string> keyPairs;
for (int i = 0; i < m; i++) {
string pub, pri;
cin >> pub >> pri;
keyPairs[pri] = pub;
}
//存主机
vector<Host> hosts(n);
for (int i = 0; i < n; i++) {
string ip;
int k;
cin >> ip >> k;
hosts[i].ip = ip;
hosts[i].users.resize(k);
for (int j = 0; j < k; j++) {
string user;
int t;
cin >> user >> t;
hosts[i].users[j].name = user;
hosts[i].users[j].publicKeys.resize(t);
for (int l = 0; l < t; l++) {
cin >> hosts[i].users[j].publicKeys[l];
}
}
}
for (int i = 0; i < q; i++) {
string user, ip, pri;
cin >> user >> ip >> pri;
bool found = false;
for (const auto& host : hosts) {
if (host.ip == ip) {
for (const auto& u : host.users) {
if (u.name == user) {
string pub = keyPairs[pri];
for (const auto& key : u.publicKeys) {
if (key == pub) {
found = true;
break;
}
}
break;
}
}
break;
}
}
cout << (found ? "Yes" : "No") << '\n';
}
return 0;
}
- Circle
比天赋,找规律题
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
ll v[100068];
int main(){
ll n;
cin>>n;
while(n--){
ll t;
cin>>t;
if(t==0)cout<<"1 ";
else cout<<t*t-t+2<<' ';
}
}
- keillempkill学姐の卷积
没有任何技巧,就是暴力模拟
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
int main() {
int n, m;
cin >> n >> m;
vector<vector<int>> ke(n, vector<int>(n));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> ke[i][j];
}
}
vector<vector<int>> matrix(m, vector<int>(m));
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
cin >> matrix[i][j];
}
}
int s = m - n + 1;
vector<vector<int>> output(s, vector<int>(s));
for (int i = 0; i < s; i++) {
for (int j = 0; j < s; j++) {
int sum = 0;
for (int ki = 0; ki < n; ki++) {
for (int kj = 0; kj < n; kj++) {
sum += ke[ki][kj] * matrix[i+ki][j+kj];
}
}
output[i][j] = sum;
}
}
for (int i = 0; i < s; i++) {
for (int j = 0; j < s; j++) {
cout << output[i][j];
if (j < s - 1) cout << " ";
}
cout << '\n';
}
return 0;
}
- 累加器
官方题解
#include<bits/stdc++.h>
using namespace std;
const int N = 2e6 + 10;
int f[N];
int c[N];
int get(int x){
return c[(x&-x)];
}
void init(){
c[1] = 1;
for(int i=1;i<=20;i++){
c[1<<i] = 1 + i;
}
for(int i=1;i<=2e6;i++){
f[i] = get(i);
f[i] += f[i-1];
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
init();
int t;
cin>>t;
while(t--){
int x,y;
cin>>x>>y;
cout<<f[x+y] - f[x]<<"\n";
}
}
我在这道题主要是收获到了还是预处理的问题以及一些二进制函数的使用,
C++位运算函数之__builtin_
这个函数是自带的GCC,不需要头文件,速度很快.
还有就是找规律的问题,找哪里的规律,是变化的规律还是每一位上的数变化的规律,比如说最后一位是1,经过几次变化又变成1.
这代码是队里一个大神的写法,预处理前缀和变化的数量,怎么变化的,用^找变化的数量,加起来就是变化的和
#include <bits/stdc++.h>
#define int long long
#define mod 998244353
#define double long double
#define PII pair<int,int>
#define PDD pair<double,double>
#define PDDD pair<PDD,double>
#define endl '\n'
using namespace std;
const int N = 2e6 + 10, SZ = (N) << 2;
const double PI = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679;
int l = 0;
int n = 1e5, k, m = 1e5;
vector<int>g[N];
vector<PII>v1, v2;
int a[N];
int b[N];
int mon[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
string date[400];
//int xx[4] = {0, 1, 0, -1}, yy[4] = {-1, 0, 1, 0};
int ct = 0;
int qpow(int x, int n) {
int ans = 1;
while (n) {
if (n & 1) {
ans *= x;
ans %= mod;
}
x *= x;
x %= mod;
n >>= 1;
}
return ans % mod;
}
void solve() {
int x,y;
cin>>x>>y;
cout<<a[x+y]-a[x]<<endl;
}
int32_t main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
// euler(1e3+10);
for(int i=1;i<=2e6;i++){
a[i]=a[i-1]+__builtin_popcount((unsigned)(i^(i-1)));
}
cin >> T;
while (T--) {
solve();
}
return 0;
}
下面是队长写的方法用找每一位变化的规律次数
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while(T--){
int a,b;
cin>>a>>b;
b=a+b;
int res=0,cnt=0;
for(int i=0;i<24;i++){
res+=a/(1LL<<i);
cnt+=b/(1LL<<i);
}
cout<<cnt-res<<'\n';
}
return 0;
}
- 推箱子
补题,队长说这道题是经典的bfs,我的思路是用bfs去搜素人和箱子的移动,记录到目标位置人物移动的距离,我判断如果在地图内人物移动之后的位置和箱子重合,那么箱子应该按照人物移动的方向距离增加,如果箱子移动之后不再地图内,那么只有人物移动箱子不会移动,最终记录箱子到达目的地人物移动的最小距离
注意分析条件,能不能移动,会不会一起移动,移动后会不会超过地图,是否箱子已经走过,注意怎么返回值和读取
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 35;
int xx[] = {0, 0, 1, -1};
int yy[] = {1, -1, 0, 0};
bool debate[MAXN][MAXN];
int dis[MAXN][MAXN][MAXN][MAXN];
int x1, ya, x2, y2, x3, y3, m;
struct Node {
int px, py, bx, by;
Node(int _px, int _py, int _bx, int _by) : px(_px), py(_py), bx(_bx), by(_by) {}
};
bool inmp(int x, int y) {
return x > 0 && x <= 30 && y > 0 && y <= 30;
}
int bfs() {
queue<Node> q;
q.push(Node(x1, ya, x3, y3));
memset(dis, -1, sizeof(dis));
dis[x1][ya][x3][y3] = 0;
while (!q.empty()) {
Node cur = q.front();
q.pop();
if (cur.bx == x2 && cur.by == y2) {
return dis[cur.px][cur.py][cur.bx][cur.by];
}
for (int i = 0; i < 4; i++) {
int nx = cur.px + xx[i], ny = cur.py + yy[i];
int nbx = cur.bx, nby = cur.by;
if (!inmp(nx, ny) || !debate[nx][ny]) continue;
if (nx == cur.bx && ny == cur.by) {
nbx = cur.bx + xx[i];
nby = cur.by + yy[i];
if (!inmp(nbx, nby) || !debate[nbx][nby]) continue;
}
if (dis[nx][ny][nbx][nby] == -1) {
dis[nx][ny][nbx][nby] = dis[cur.px][cur.py][cur.bx][cur.by] + 1;
q.push(Node(nx, ny, nbx, nby));
}
}
}
return -1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(nullptr);
cin >> x1 >> ya >> x2 >> y2 >> x3 >> y3 >> m;
memset(debate, true, sizeof(debate));
for (int i = 0; i < m; i++) {
int px, py;
cin >> px >> py;
debate[px][py] = false;
}
cout << bfs() << endl;
return 0;
}
- 暴食之史莱姆
注意到,当史莱姆的邻居体积比自己大时,可以使邻居吃掉其他史莱姆来使邻居体积缩小,再被史莱姆吃掉
那么,通过观察容易得到。在只考虑左侧史莱姆的情况,编号为i的史莱姆能吃掉的同伴个数,一定是左边第一个比i体积小的史莱姆所能吃的数量。
右侧同理。由于史莱姆可以优先选择左右中较大者吃,且吃 的条件为大于等于,所以答案就是左侧+右侧能吃的个数。
#include <bits/stdc++.h>
using namespace std;
int n;
int arr[200005];
int ans[200005];
void solve(){ ////补K 单调栈--维护一个单调的序列,当栈顶元素比现在元素大时就pop.再push当前元素
cin>>n;
for(int i=1;i<=n;i++) cin>>arr[i];
stack<int> stk;
for(int i=1;i<=n;i++){
while(stk.size()&&stk.top()>arr[i]) stk.pop();
ans[i]+=stk.size();
stk.emplace(arr[i]);
}
while(stk.size()) stk.pop();
for(int i=n;i>=1;i--){
while(stk.size()&&stk.top()>arr[i]) stk.pop();
ans[i]+=stk.size();
stk.emplace(arr[i]);
}
for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
}
signed main() {
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int t=1;
//cin>>t;
while(t--){
solve();
}
return 0;
}
本文作者:冬天的睡袋
本文链接:https://www.cnblogs.com/dontian/p/18335336
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步