L1-058 6翻了
if+while循环处理相同字符个数
L1-059 敲笨钟
rfind和erase的妙用
L1-064 估值一亿的AI核心代码
正则表达式
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;cin>>n;
string s;getline(cin,s);
while(n--){
getline(cin,s);
cout<<s<<endl;
s=regex_replace(s,regex(R"(\s+)")," ");
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"( \')"),"'");
if(s[0]==' ')s.erase(0,1);
if(s.back()==' ')s.pop_back();
for(auto &i:s){
if(i!='I')i=tolower(i);
}
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;
}
}
L3-001 凑零钱
01背包(先用大物品再用小物品)+输出路径
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define all(x) x.begin(),x.end()
#define no cout<<"No"<<endl
#define yes cout<<"Yes"<<endl
#define endl '\n'
// #define x first
// #define y second
typedef pair<int,int> PII;
const int N=200010;
const int mod=998244353;
const int INF=0x3f3f3f3f3f3f3f3f;
int dp[N];
int vis[N][105];
void solve(){
int n,m;cin>>n>>m;
vector<int>v(n);
for(int i=0;i<n;i++)cin>>v[i];
sort(all(v),greater<int>());
dp[0]=1;
for(int i=0;i<n;i++){
for(int j=m;j>=v[i];j--){
if(dp[j-v[i]]){
dp[j]=1;
vis[i][j]=1;
}
}
}
vector<int>ans;n--;
if(dp[m])while(m){
if(vis[n][m]){
ans.push_back(v[n]);
m-=v[n];
}
n--;
}
if(ans.size()){
for(int i=0;i<ans.size();i++){
if(i)cout<<' '<<ans[i];
else cout<<ans[i];
}
}else cout<<"No Solution\n";
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int _=1;
while(_--)solve();
return 0;
}
L3-002 特殊堆栈
树状数组+二分(求第k小)
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) (x&(-x))
const int N=1e5+10;
int tr[N];
void add(int t,int val){
for(int i=t;i<N;i+=lowbit(i)){
tr[i]+=val;
}
}
int query(int t){
int res=0;
for(int i=t;i;i-=lowbit(i)){
res+=tr[i];
}
return res;
}
int main(){
int n;cin>>n;
stack<int>st;
for(int i=0;i<n;i++){
string s;cin>>s;
if(s=="Pop"){
if(st.empty()){
cout<<"Invalid\n";
continue;
}
int x=st.top();st.pop();
add(x,-1);
cout<<x<<endl;
}else if(s=="PeekMedian"){
if(st.empty()){
cout<<"Invalid\n";
continue;
}
int x=((int)st.size()+1)/2;
int l=0,r=N;
while(l+1!=r){
int mid=l+r>>1;
if(query(mid)>=x)r=mid;
else l=mid;
}
cout<<r<<endl;
}else{
int x;cin>>x;
st.push(x);
add(x,1);
}
}
}
L3-003 社交集群
稍微有点思维的并查集
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int root[N];
int sz[N];
int find(int a){
if(a==root[a])return a;
return root[a]=find(root[a]);
}
void merge(int a,int b){
int ra=find(a),rb=find(b);
if(ra>rb)swap(ra,rb);
sz[ra]+=sz[rb];
root[rb]=ra;
}
int main(){
int n;cin>>n;
for(int i=0;i<N;i++)root[i]=i;
for(int i=0;i<n;i++){
string s;cin>>s;
string t;
for(auto i:s){if(i==':')break;
t+=i;
}
int k=stoi(t);
int a;cin>>a;
sz[find(a)]++;
for(int j=0;j<k-1;j++){
int b;cin>>b;
merge(a,b);
}
}
vector<int>ans;
for(int i=1;i<N;i++){
if(sz[find(i)])
if(i==find(i))
ans.push_back(sz[find(i)]);
}
sort(ans.begin(),ans.end(),greater<int>());
cout<<ans.size()<<endl;
for(int i=0;i<ans.size();i++){
if(i)cout<<' ';
cout<<ans[i];
}
}
L3-004 肿瘤诊断
三维bfs
#include<bits/stdc++.h>
using namespace std;
int dir[6][3]={0,0,1,0,0,-1,0,1,0,0,-1,0,-1,0,0,1,0,0};
int g[1300][130][70];
int book[1300][130][70];
int main(){
int m,n,l,t;cin>>m>>n>>l>>t;
for(int i=0;i<l;i++){
for(int j=0;j<m;j++){
for(int k=0;k<n;k++){
cin>>g[j][k][i];
}
}
}
int ans=0;
for(int i=0;i<l;i++){
for(int j=0;j<m;j++){
for(int k=0;k<n;k++){
if(!book[j][k][i]&&g[j][k][i]==1){
int cnt=1;
book[j][k][i]=1;
queue<array<int,3>>q;
q.push({j,k,i});
while(q.size()){
auto [a,b,c]=q.front();
q.pop();
for(int p=0;p<6;p++){
int tx=a+dir[p][0],ty=b+dir[p][1],tz=c+dir[p][2];
if(tx<0||ty<0||tz<0||tx>=m||ty>=n||tz>=l||book[tx][ty][tz]||g[tx][ty][tz]==0)continue;
book[tx][ty][tz]=1;
cnt++;
q.push({tx,ty,tz});
}
}
if(cnt>=t)ans+=cnt;
}
}
}
}
cout<<ans<<endl;
}
L3-005 垃圾箱分布
刚开始理解错题意了,就是个裸的Dijkstra
O(m*n+klogn)
L3-007 天梯地图
经典Dijkstra+dfs
#include<bits/stdc++.h>
using namespace std;
const int N=550;
const int INF=0x3f3f3f3f;
vector<array<int,3>>v[N];
int d1[N];
int d2[N];
int n,m;
int st,ed;
void Dijkstra1(){
for(int i=0;i<n;i++)d1[i]=INF;
vector<int>book(n);
d1[st]=0;
for(int i=0;i<n;i++){
int mn=INF,t;
for(int j=0;j<n;j++){
if(!book[j]&&mn>=d1[j]){
mn=d1[j];
t=j;
}
}
if(book[t])continue;
book[t]=1;
for(auto [j,w1,w2]:v[t]){
if(book[j])continue;
d1[j]=min(d1[j],w1+mn);
}
}
}
void Dijkstra2(){
for(int i=0;i<n;i++)d2[i]=INF;
vector<int>book(n);
d2[st]=0;
for(int i=0;i<n;i++){
int mn=INF,t;
for(int j=0;j<n;j++){
if(!book[j]&&mn>=d2[j]){
mn=d2[j];
t=j;
}
}
if(book[t])continue;
book[t]=1;
for(auto [j,w1,w2]:v[t]){
if(book[j])continue;
d2[j]=min(d2[j],w2+mn);
}
}
}
int cnt=INF;
vector<int>ans1;
vector<int>ans2;
vector<int>tmp;
void dfs1(int t,int fa,int ndist,int ncnt){
if(ndist>d1[t])return;
if(t==ed){
if(ncnt<cnt){
ans1=tmp;
cnt=ncnt;
}
return;
}
for(auto [j,a,b]:v[t]){
if(j==fa)continue;
tmp.push_back(j);
dfs1(j,t,ndist+a,ncnt+1);
tmp.pop_back();
}
}
int dist=INF;
void dfs2(int t,int fa,int nTm,int ndist){
if(nTm>d2[t])return;
if(t==ed){
if(ndist<dist){
ans2=tmp;
dist=ndist;
}
return;
}
for(auto [j,a,b]:v[t]){
if(j==fa)continue;
tmp.push_back(j);
dfs2(j,t,nTm+b,ndist+a);//这里的参数一定要用对啊,一直忘
tmp.pop_back();
}
}
int main(){
cin>>n>>m;
for(int i=0;i<m;i++){
int a,b,c,d,e;cin>>a>>b>>c>>d>>e;
v[a].push_back({b,d,e});
if(!c)v[b].push_back({a,d,e});
}
cin>>st>>ed;
Dijkstra1();
Dijkstra2();
tmp.push_back(st);
dfs1(st,st,0,0);
dfs2(st,st,0,0);
if(ans1==ans2){
printf("Time = %d; Distance = %d: %d",d2[ed],d1[ed],st);
for(int i=1;i<ans1.size();i++){
printf(" => %d",ans1[i]);
}
}else{
printf("Time = %d: %d",d2[ed],st);
for(int i=1;i<ans2.size();i++){
printf(" => %d",ans2[i]);
}cout<<'\n';
printf("Distance = %d: %d",d1[ed],st);
for(int i=1;i<ans1.size();i++){
printf(" => %d",ans1[i]);
}
}
}
L3-011 直捣黄龙
经典Dijkstra+dfs
#include<bits/stdc++.h>
using namespace std;
#define PII pair<int,int>
unordered_map<string,int>mp;
unordered_map<int,string>mp2;
const int N=220;
const int INF=0x3f3f3f3f;
int val[N];
vector<PII>v[N];
int idx=0;
int d[N];
string st,ed;
int n,k;
void Dijkstra() {
for(int i=0; i<n; i++)d[i]=INF;
d[mp[st]]=0;
vector<int>book(n);
for(int i=0; i<n; i++) {
int mn=INF,t;
for(int j=0; j<n; j++) {
if(!book[j]&&mn>=d[j]) {
mn=d[j];
t=j;
}
}
if(book[t])continue;
book[t]=1;
for(auto [j,w]:v[t]) {
if(book[j])continue;
if(d[j]>mn+w) {
d[j]=mn+w;
}
}
}
}
vector<int>ans;
vector<int>tmp;
int ans2,cnt,sum,dist;
void dfs(int t,int fa,int nsum,int ncnt,int ndist) {
if(ndist>d[t])return;
if(t==mp[ed]) {
ans2++;
if(ncnt>cnt) {
ans=tmp;
cnt=ncnt;
sum=nsum;
} else if(ncnt==cnt&&nsum>sum) {
ans=tmp;
cnt=ncnt;
sum=nsum;
}
return;
}
for(auto [j,w]:v[t]) {
if(j==fa)continue;
tmp.push_back(j);
dfs(j,t,nsum+val[j],ncnt+1,ndist+w);
tmp.pop_back();
}
}
int main() {
cin>>n>>k;
cin>>st>>ed;
mp[st]=idx;mp2[idx++]=st;
mp[ed]=idx;mp2[idx++]=ed;
for(int i=0; i<n-1; i++) {
string a;int b;
cin>>a>>b;
if(!mp.count(a)) {
mp[a]=idx;
mp2[idx++]=a;
}
val[mp[a]]=b;
}
for(int i=0; i<k; i++) {
string a,b;int c;
cin>>a>>b>>c;
v[mp[a]].push_back({mp[b],c});
v[mp[b]].push_back({mp[a],c});
}
Dijkstra();
tmp.push_back(mp[st]);
dfs(mp[st],mp[st],0,0,0);
for(int i=0; i<ans.size(); i++) {
if(i)cout<<"->";
cout<<mp2[ans[i]];
}cout<<endl;
cout<<ans2<<' '<<d[mp[ed]]<<' '<<sum;
}
L3-022 地铁一日游
题意太抽象
Floyd写错了
#include<bits/stdc++.h>
using namespace std;
const int N=220;
const int INF=0x3f3f3f3f;
int d[N][N];
set<int>st[N];
int ru[N];
string line;
vector<int>v;
vector<int>book(N);
void dfs(int t){
for(auto j:st[t]){
if(book[j])continue;
book[j]=1;
v.push_back(j);
dfs(j);
}
}
int main(){
int n,m,k;cin>>n>>m>>k;getline(cin,line);
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)d[i][j]=INF,d[i][i]=0;
for(int i=0;i<m;i++){
getline(cin,line);
stringstream ssin(line);
string s;vector<int>tmp;
while(ssin>>s)tmp.push_back(stoi(s));
for(int i=0;i<tmp.size();i+=2){
if(i==0)ru[tmp[i]]=1;
if(i==tmp.size()-1){ru[tmp[i]]=1;break;}
d[tmp[i]][tmp[i+2]]=min(d[tmp[i]][tmp[i+2]],tmp[i+1]);
d[tmp[i+2]][tmp[i]]=min(d[tmp[i+2]][tmp[i]],tmp[i+1]);
}
}
for(int k = 1; k <= n; k++)//Floyd
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(i!=j)d[i][j] = min(d[i][j],d[i][k]+d[k][j]);
for(int i=1;i<=n;i++){
map<int,int>mp;
st[i].insert(i);
for(int j=1;j<=n;j++){
if(d[i][j]==INF)continue;
mp[2+d[i][j]/k]=max(mp[2+d[i][j]/k],d[i][j]);
}
for(int j=1;j<=n;j++){
if(d[i][j]==INF)continue;
if(d[i][j]==mp[2+d[i][j]/k]||ru[j]==1){
st[i].insert(j);
}
}
}
int q;cin>>q;
while(q--){
int x;cin>>x;
v.clear();
book.assign(N,0);
book[x]=1;
dfs(x);
for(auto i:v){
st[x].insert(i);
}
int fir=1;
for(auto i:st[x]){
if(fir){cout<<i;fir=0;}
else cout<<' '<<i;
}cout<<endl;
}
}
L3-025 那就别担心了
dfs逆向思维(一直误以为是拓扑排序)
L3-031 千手观音
离散化+优先队列+拓扑排序
L3-032 关于深度优先搜索和逆序对的题应该不会很难吧这件事
树状数组求树上逆序对