0324-0331题解反思

最近我突然发现,写题解是常常会遗忘的,然而题目中的一些技巧才是永恒的,那么接下来的题解,我应该对以前的题目含有的这些技巧进行一些深刻的复盘。

知识点模块

1.当我们要实现一个图形的字符串的倒置,比如把福倒过来,我们可以进行以下的操作:先进行 行的交换,在进行列的倒置,我们需要用到swap和reverse函数
vector<string>ve(n)
getline(cin,s)
for(int i=0;i*2<n;i++) swap(ve[i],ve[n-i-1]
for(int i=0;i<n;i++) reverse(ve[i].begin(),ve[i].end())
这样便可以实现把福变成倒福了

2.当我们要对一串前后都有空格的字符串进行空格的删减,可以采取先删除尾部的空格,然后reverse以后再删除尾部的空格在reverse即可,我们需要用到string中的pop_back函数和reverse函数
getline(cin,s)
while(s.back())==" ") s.pop_back()
reverse(s.begin(),s.end())
while (s.back() == ' ') s.pop_back();
reverse(s.begin(), s.end());
这样便实现了空格的删除,无论前后有多少恶心你的空格

3.学习dfs树的建立,遍历dfs树来寻找最深深度和最小路径,我们需要使用二维的vector来实现
这是图的建立,[]代表了有n行,()代表一行有n个
vector<int>ve[10005];
ve[i].push_back(x)

这是寻找最深深度

点击查看代码
void dfslen(int x,int dep)
{   if(ve[i].size()==0) maxdep=max(maxdep,dep);
    for(auto t:ve[x]) dfs(x,dep+1);
}

这是寻找最小路径

点击查看代码
bool dfsmin(int x,int dep)//用来寻找最小路径
{
	if(maxdep==dep) return 1;
	bool res=0;
	for(auto t:ve[x]){
		if((dfsmin(t,dep+1)){
			if(road[x]>t) road[x]=t;
			res=true;
		}
	}
	return res;
}

4.二进制位数的加法,如111我们可以写成100+010+001,在前世档案这题便用上了

题解模块

福到了
这题利用我们上述提到的知识点模块1,然后转换后对比一下是否与原来的相等然后按要求输出就可以了

点击查看代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	string s,th;
	cin>>th>>n;
	vector<string>ve(n);
	getline(cin,s);
	for(auto &s:ve)//c++中的循环输入等价于for(int i=0;i<n;i++) getline(cin,ve[i]) 
	{
		getline(cin,s);
	}
	
	auto vc=ve;
	for(int i=0;i*2<n;i++)
	{
		swap(vc[i],vc[n-i-1]);
	}
	
	for(int i=0;i<n;i++)
	{
		reverse(vc[i].begin(),vc[i].end());
	}
	
	if(ve==vc) cout<<"bu yao dao le"<<endl;
	
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++){
			if(vc[i][j]==' ')cout<<' ';
			else cout<<th;
		}	
		cout<<endl;
	}
	return 0;
}

前世档案
这题仔细观察一下其实向左走对应二进制中的0,往右走对应二进制中的1,结果就是1+该二进制数,而二进制例如101又可以等于100+001因此可以根据N或Y让1每次加上一个二进制数即可

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long

void solve()
{
    int n,m;
    cin>>n>>m;
    while(m--)
    {    
        int ans=1;
        string s;
        cin>>s;
        for(int i=0;i<n;i++)
        {
            if(s[i]=='n') ans+=(1<<(n-i-1));
        }
        cout<<ans<<endl;
        
    }
    
    
}



signed main()
{
    solve();
    
}

抢红包
这一题其实也是简单的模拟题,但是注意题给的两个排序的要求,学习乐爷的思路就是,先开一个数组放1-10,然后自定义排序规则让1-10重新排序,再对应输出
关键的代码在这

点击查看代码
  vector<int>vi(n);   
    iota(vi.begin(),vi.end(),1);
    sort(vi.begin(),vi.end(),[&](int a,int b){
        if(ve[a]!=ve[b]) return ve[a]>ve[b];
        if(ce[a]!=ce[b]) return ce[a]>ce[b];
        return a<b;
    });

题解代码

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long

int main () {
    // ios::sync_with_stdio(0);
    // cin.tie(0);

    int n,m;
    cin>>n;
    vector<int>ve(n+1),ce(n+1);//ve来记录获得的钱,ce来记录获得了多少个红包
    for(int i=1;i<=n;i++)
    {
        cin>>m;
        while(m--)
        {
            int x,k;
            cin>>x>>k;
            ve[i]-=k;
            ve[x]+=k;
            ce[x]++;
        }
    }
    
    vector<int>vi(n);   
    iota(vi.begin(),vi.end(),1);
    sort(vi.begin(),vi.end(),[&](int a,int b){
        if(ve[a]!=ve[b]) return ve[a]>ve[b];
        if(ce[a]!=ce[b]) return ce[a]>ce[b];
        return a<b;
    });
    
    for(auto i:vi)
    {
        cout<<i<<" ";
        if(ve[i]<0)
        {
            cout<<"-";
            ve[i]=-ve[i];
        }
        cout<<ve[i]/100<<'.';
        printf("%02d\n",ve[i]%100);
        
    }
    
    

    
}

7-3 谁能进图书馆
简单的模拟题,但是当时没有注意到两个人都可以进且不是必须的也要输出第一行

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long

signed main () {
   int x,y,t1,t2;
   cin>>x>>y>>t1>>t2;
   if(t1<x&&t2>=y||t2<x&&t1>=y){
       cout<<t1<<"-Y "<<t2<<"-Y"<<endl;
       if(t1>t2) cout<<"qing 1 zhao gu hao 2";
       else cout<<"qing 2 zhao gu hao 1";
   }
   else if(t1>=x&&t2>=x) {
       cout<<t1<<"-Y "<<t2<<"-Y"<<endl;
       cout<<"huan ying ru guan";
   }
   else if(t1<x&&t2<x) {
       cout<<t1<<"-N "<<t2<<"-N"<<endl;
       cout<<"zhang da zai lai ba";

   }
   else
   {
       if(t1>t2) 
       {
           cout<<t1<<"-Y "<<t2<<"-N"<<endl;
           cout<<"1: huan ying ru guan";
       }
       else {
            cout<<t1<<"-N "<<t2<<"-Y"<<endl;
           cout<<"2: huan ying ru guan";
       }
       
   }
   
   
}

7-7 出租
我们每次再处理像“{8,6,5,4,3}”的这样字符串的输出的时候,都会对逗号感到烦恼,其实只要单独输出第一个8 后面输出,i即可,这题题意也很简洁,但是注意代码的简化和时间的控制

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int,int>pii;
int arr[10],st[10];
int idex[15];
signed main () {
    string s;
    cin>>s;
    
    for(int i=0;i<s.size();i++){
        st[s[i]-'0']=1;
    }
    int num=0;
    for(int i=9;i>=0;i--) if(st[i]) arr[num++]=i;
    
    for(int i=0;i<s.size();i++){
        for(int j=0;j<=9;j++){
            if(s[i]-'0'==arr[j]) {
                idex[i]=j;
                break;}
                
        }
    }
    
 //   for(int i=0;i<=10;i++) cout<<idex[i]<<" ";
    
    cout<<"int[] arr = new int[]{"<<arr[0];
    for(int i=1;i<num;i++) cout<<","<<arr[i];
    cout<<"};"<<endl;
    
    
    cout<<"int[] index = new int[]{"<<idex[0];
    for(int i=1;i<=10;i++) cout<<","<<idex[i];
    cout<<"};";
    
    
    


   return 0;
   
}

7-8连续因子
这题因为2的31次方才到2e9,但1乘2乘3乘到13就有6e9了,所以我们只需枚举位数n,然后枚举该位数下的起点,在枚举它的后n-1位数相乘看是否大于这个数,若大于就跳出循环,然后来检查这个数是否可以被输入的数取余,若可以打印即可,质数的因子只有1和它本身,所以也需要判断是否为质数

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N=1e9+7;
#define int long long int
bool isprime(int x)
{
	if(x==1) return false ;
	else {
		for(int i=2;i*i<x;i++)
		{
			if(x%i==0) return false ;
		}
	}
	return true;
	
}



void solve()
{
	int n;
	cin>>n;
	if(isprime(n)) {
	cout<<1<<endl<<n;
	return ;
	}
	
	
	vector<int> ans[20];
	int maxx=0;
	for(int i=1;i<=13;i++){//枚举位数
	for(int j=2;j+i<=1000;j++){//这个位数下枚举的起点	 
		int cur=1;
		for(int k=j;k<j+i;k++){//从起点枚举到他后面的位数-1个数
			cur*=k;
			if(cur>n) break;
		}
		
		if(n%cur==0){
			for(int k=j;k<=j+i;k++) ans[i].emplace_back(k);
			maxx=i;
			break;
		}
	}
	}
	cout<<maxx<<endl;
	for(int i=0;i<maxx;i++){
		cout<<ans[maxx][i];
		if(i!=maxx-1) cout<<"*";
}
	
}

signed main()
{
	int t=1;
//	cin>>t;
	while(t--)solve();
	
}

7-11 病毒溯源
这题便是dfs树的应用了,利用上面的知识点,然后实现即可,注意根节点是未被遍历过的数,也就是源头root要注意是哪个

点击查看代码
#include <bits/stdc++.h>
using namespace std;
int start[10005]={0}, road[10005],maxdep,dep,root;
unordered_map<int,bool> mp;
int n;
vector<int>ve[10005];
void dfslen(int x,int dep)
{
    if(ve[x].size()==0) maxdep=max(maxdep,dep);
    for(auto t:ve[x]) dfslen(t,dep+1);
}
//寻找最小路径 画图多理解一下
bool dfsmin(int x,int dep)
{
    if(dep==maxdep) return 1;
    bool res=0;
    for(auto t:ve[x]){
        if(dfsmin(t,dep+1)){
            if(t<road[x]) road[x]=t;
            res=true;
        }
    }
    
    return res;
}


int main()
{
    
    cin>>n;
    
    for(int i=0;i<n;i++)
    {
        int k;
        cin>>k;
        while(k--){
            int x;
            cin>>x;
            ve[i].push_back(x);
            mp[x]=1;
        }
    }
    //寻找病毒的源头
    for(int i=0;i<n;i++){
        if(!mp[i]){
            root=i;
         
        }
    }
 
    //寻找最长的长度
    dfslen(root,1);
    cout<<maxdep<<endl;
    
    //寻找最小路径
    for(int i=0;i<n;i++) road[i]=1e9;
    dfsmin(root,1);
    
    int cur=root;
    cout<<root;
    while(road[cur]!=1e9){
        cout<<" "<<road[cur];
        cur=road[cur];
    }
    
    
    
    
}

7-10 列车厢调度
这题先别学我的做法,因为我只拿了20分,等我再改改

点击查看代码
using namespace std;
//#define int long long
stack<int>train3,train2;
signed main () {
   string a,b;
   vector<string>ve;
   cin>>a>>b;
   for(int i=0;i<a.size();i++){
       if(i!=a.size()-1){
           train3.push(a[i]-'A');
            ve.push_back("1->3");
       }
       else {
           train2.push(a[i]-'A');
          ve.push_back("1->2");
       }
   }
   
   while(train3.size()){
       int k=train3.top();
       train3.pop();
       train2.push(k);
       ve.push_back("3->2");
   }
   bool check=1;
   int pos=b.size()-1;
   while(train2.size()){
       int q=train2.top();
       train2.pop();
       if(q+'A'!=b[pos]) {
           check=0;
           cout<<"Are you kidding me?";
           return 0;
       }
       else pos--;
   }
   
   if(check){
       for(auto t:ve){
           cout<<t<<endl;
       }
   }
   
   
}


还有广州大学ACM那场题解还没补

posted on 2024-03-31 20:39  swj2529411658  阅读(25)  评论(0)    收藏  举报

导航