最近我突然发现,写题解是常常会遗忘的,然而题目中的一些技巧才是永恒的,那么接下来的题解,我应该对以前的题目含有的这些技巧进行一些深刻的复盘。
知识点模块
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那场题解还没补
标签:0324,ve,int,题解,cin,long,dep,ce,0331 From: https://www.cnblogs.com/swjswjswj/p/18105631