2025寒假训练第三周
天梯赛
考点:模拟基础(注意特判)
L1-8 乘法口诀数列
把每两位的乘积放到栈里,再放到动态数组里即可,但是注意特判乘积为0的情况,比如2 5 10这个样例
#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define int long long
using pii = pair<int, int>;
using triple = tuple<int, int, int>;
int dx[] = {0, 0, -1, 1, -1, -1, 1, 1};
int dy[] = {1, -1, 0, 0, -1, 1, -1, 1};
vector<int>ve;
stack<int>a;
void getn(int x) {
if(!x) a.push(x);//处理 2 5 10这样的数据
while (x) {
a.push(x % 10);
x /= 10;
}
while(a.size())
{
ve.push_back(a.top());
a.pop();
}
}
void solve() {
int a, b, n;
cin >> a >> b >> n;
ve.push_back(a);
ve.push_back(b);
getn(a*b);
int p1=1;
while (ve.size() < n) {
getn(ve[p1]*ve[p1+1]);
p1++;
}
cout<<ve[0];
for(int i=1;i<n;i++)
{
cout<<" "<<ve[i];
}
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0);
int t = 1;
// cin>>t;
while (t--) solve();
}
L2-2 病毒溯源
这题其实写好几遍了,但是找这个最小路径的递归过程还是没有办法很丝滑的写出来,其实就是先对每层从小到大排序一下,然后如果长度符合的第一条路径就是最小的
#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define int long long
using pii=pair<int,int>;
using triple=tuple<int,int,int>;
int dx[]={0,0,-1,1,-1,-1,1,1};
int dy[]={1,-1,0,0,-1,1,-1,1};
vector<int>tr[10005];
int din[10005];
int mx=0;
int ans[10005];
void dfslen(int x,int dep)
{
if(tr[x].size()==0) {
mx=max(mx,dep);
}
for(auto i:tr[x]){
dfslen(i,dep+1);
}
}
bool check=0;
void dfs(int x,int dep)
{
if(dep==mx) {
check=1;
return ;
}
for(auto i:tr[x]){
dfs(i,dep+1);
if(check){//先往下走判断是不是最大长度
if(i<ans[x]) ans[x]=i;
}
}
}
void solve()
{
for(int i=0;i<10005;i++) ans[i]=1e6;
int n;
cin>>n;
for(int i=0;i<n;i++)
{
int k; cin>>k;
while(k--)
{
int x; cin>>x;
tr[i].push_back(x);
din[x]++;
}
}
int root=0;
for(int i=0;i<n;i++)
{
if(din[i]==0)
{
root=i;
break;
}
}
dfslen(root,1);
for(int i=0;i<n;i++) sort(tr[i].begin(),tr[i].end());
cout<<mx<<"\n";
dfs(root,1);
cout<<root;
while(ans[root]!=1e6){
cout<<" "<<ans[root];
root=ans[root];
}
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0);
int t=1;
// cin>>t;
while(t--) solve();
}
学着用正则表达式
\b用来匹配单词
#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define int long long
using pii=pair<int,int>;
using triple=tuple<int,int,int>;
int dx[]={0,0,-1,1,-1,-1,1,1};
int dy[]={1,-1,0,0,-1,1,-1,1};
string s;
void solve()
{
int n;
cin>>n;
cin.ignore();
while(n--)
{
string s;
getline(cin,s);
cout<<s<<"\n";
if(s.front()== ' ') s.erase(s.begin());
if(s.back()==' ') s.pop_back();
s = regex_replace(s, regex(R"(\s+)"), " ");
if(s.front() == ' ') s.erase(s.begin());
if(s.back() == ' ') s.pop_back();
s = regex_replace(s, regex(R"( !)"), "!");
s = regex_replace(s, regex(R"( ,)"), ",");
s = regex_replace(s, regex(R"( \.)"), ".");
s = regex_replace(s, regex(R"( \?)"), "?");
s = regex_replace(s, regex(R"( ')"), "'");
for (auto &c : s) {
if(c != 'I') c = tolower(c);
}
s = regex_replace(s, regex(R"(\bcan you\b)"), "_I can");
s = regex_replace(s, regex(R"(\bcould you\b)"), "_I could");
s = regex_replace(s, regex(R"(\bI\b)"), "you");
s = regex_replace(s, regex(R"(\bme\b)"), "you");
s = regex_replace(s, regex(R"(\?)"), "!");
s = regex_replace(s, regex(R"(\b_I\b)"), "I");
cout << "AI: " << s << endl;
}
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0);
int t=1;
// cin>>t;
while(t--) solve();
}
牛客
小L的位运算
按照每一位来看,如果a异或b不等于c的,就去组成00,01,10,11统计对应数量
然后问题就是选择策略,到底是交换两位,还是反置来的划算,如果x<2*y ,那么当然每一对直接反置一位代价就最小,反之,分类讨论最多数量的那个大于三个总和,与不大于三个总和的情况
#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define int long long
using pii=pair<int,int>;
using triple=tuple<int,int,int>;
int dx[]={0,0,-1,1,-1,-1,1,1};
int dy[]={1,-1,0,0,-1,1,-1,1};
int ve[5];
void solve()
{
int n,x,y;
cin>>n>>x>>y;
string a,b,c;
cin>>a>>b>>c;
for(int i=0;i<n;i++)
{
int na=a[i]-'0',nb=b[i]-'0',nc=c[i]-'0';
// cout<<na<<" "<<nb<<" "<<nc<<" "<<na<<"\n";
if( (na^nb )!=nc)
{
ve[1]+=(a[i]=='0'&&b[i]=='0');
ve[2]+=(a[i]=='0'&&b[i]=='1');
ve[3]+=(a[i]=='1'&&b[i]=='0');
ve[4]+=(a[i]=='1'&&b[i]=='1');
}
}
// for(int i=1;i<=4;i++) cout<<ve[i]<<" ";
int ans=0;
ans=(ve[1]+ve[2]+ve[3]+ve[4])*x;
sort(ve+1,ve+5);
if(ve[4]>ve[1]+ve[2]+ve[3]){
ans=min(ans,(ve[1]+ve[2]+ve[3])*y+(ve[4]-ve[1]-ve[2]-ve[3])*x);//1 2 3都和4去配对消除 剩下的4用x代价来消除
}else{
ans=min(ans,(ve[1]+ve[2]+ve[3]+ve[4])/2*y+(ve[1]+ve[2]+ve[3]+ve[4])%2*x);
}
cout<<ans;
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0);
int t=1;
// cin>>t;
while(t--) solve();
}
小L的井字棋
双方落子数量相同。这是个最重要的条件
当棋子数量小于2时,无论怎么摆小L明显都能赢
当棋子数量为4时,我们只需要要把这一个棋子改为X,再检查一下是不是能赢即可
当棋子数量为3时,我们就分类讨论把这连续两颗放的位置,然后最后再检查是否能赢
#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define int long long
using pii=pair<int,int>;
using triple=tuple<int,int,int>;
int dx[]={0,0,-1,1,-1,-1,1,1};
int dy[]={1,-1,0,0,-1,1,-1,1};
char a[15][15];
void solve()
{
int sum=0;
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++){
cin>>a[i][j];
sum+=(a[i][j]=='X');
}
}
auto check=[&]()->bool
{
//横三连
for(int i=1;i<=3;i++)
{
if(a[i][1]=='X'&&a[i][2]=='X'&&a[i][3]=='X') return 1;
}
//竖三连
for(int i=1;i<=3;i++)
{
if(a[1][i]=='X'&&a[2][i]=='X'&&a[3][i]=='X') return 1;
}
if(a[1][1]=='X'&&a[2][2]=='X'&&a[3][3]=='X') return 1;
if(a[3][1]=='X'&&a[2][2]=='X'&&a[1][3]=='X') return 1;
return 0;
};
if(sum<=2) cout<<"Yes";
else {
if(sum==4){
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++){
if(a[i][j]=='G') a[i][j]='X';
}
}
if(check()) cout<<"Yes";
else cout<<"No";
}
if(sum==3)
{
vector<pii>ve;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++) if(a[i][j]=='G') ve.push_back({i,j});
int f1=0,f2=0,f3=0;
// for(auto [x,y]:ve){
// cout<<x<<" "<<y<<"\n";
// }
int x1=ve[0].first,y1=ve[0].second;
int x2=ve[1].first,y2=ve[1].second;
a[x1][y1]=a[x2][y2]='X';
if(check()) f1=1;
a[x1][y1]=a[x2][y2]='G';
x1=ve[0].first,y1=ve[0].second;
x2=ve[2].first,y2=ve[2].second;
a[x1][y1]=a[x2][y2]='X';
// for(int i=1;i<=3;i++)
// {
// for(int j=1;j<=3;j++) cout<<a[i][j];
// cout<<"\n";
// }
//
if(check()) f2=1;
a[x1][y1]=a[x2][y2]='G';
x1=ve[1].first,y1=ve[1].second;
x2=ve[2].first,y2=ve[2].second;
a[x1][y1]=a[x2][y2]='X';
if(check()) f3=1;
a[x1][y1]=a[x2][y2]='G';
// cout<<f1<<" "<<f2<<" "<<f3<<"\n";
if(f1||f2||f3) cout<<"Yes";
else cout<<"No";
}
}
cout<<"\n";
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0);
int t=1;
cin>>t;
while(t--) solve();
}
后面两场牛客的题还在补
posted on 2025-02-16 05:58 swj2529411658 阅读(15) 评论(0) 收藏 举报
浙公网安备 33010602011771号