美团8.15 笔试复盘

第一题:
第一行T表示有T组来判断,第二行是这个第一组的元素个数,接着是元素的全部输出,,,,不断输出T组
输出是对每一组的判断,如果能排列组成1-2 -3这样的话输出yes不然输出NO

#include<bits/stdc++.h>
using namespace std;
int main(){
    int T; cin>>T;
    vector<vector<int>>res;
    for(int i=0;i<T;i++){
    	int size;
        cin>>size;
        vector<int>temp(size);
        for(int j=0;j<size;j++)
        	cin>>temp[j];
        res.push_back(temp);	
    }
    /完成输入 开始进行判断
    for(int i=0;i<res.size();i++){
        int flag=1;
        int len=res[i].size();
        sort(res[i].begin(),res[i].end());
        for(int j=0;j<=len-2;j++){
            if(j==0 && res[i][j]!=1){
                flag=0;
                break;
            }
            if(res[i][j]+1!=res[i][j+1]){
                flag=0;
                break;
            }            
        }
        if(flag==0)
            cout<<"NO"<<endl;
        if(flag==1)
            cout<<"Yes"<<endl;
    }

    return 0;
    
}

第二题:
题目很简单,输入一个字符串,问在字符串尾巴最少添加几个字符能够让新字符串变成回文串!
  这个题目fuzhu用的方法非常巧妙,其实还是老实点吧。
  假设字符串长度为N,我们直到最长也不会超过N-1个辅助字符,关键在于原始字符串的末尾处有几个字符能够构成回文串了! 我们的答案就是N-末尾回文串最大长度。
为了方便处理,我们将原来的字符串进行倒序,然后固定左端,看看最长的回文串长度!(原来回文,倒序还是回文)

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull mod =10000;

int main() {

	string s;
	cin>>s;
	int n = s.size();
	
	ull s1 = 0,s2 = 0,ba = 1;
	int ans = 1;
	
		int i=0,jj=n-1;
		while(i<jj){
			string now=s.substr(0,jj+1);
			string temp=now;
			reverse(now.begin(),now.end());
			if(now==temp){ ans=jj+1; break;}
			else jj--;
		}
		cout<<n-ans;

	
	return 0;
}

或者更快的是:

#include <bits/stdc++.h>
using namespace std;

int main() {

	string s;
	cin>>s;
	int n = s.size();
	int ans = 1;
	
	for(int j=n-1;j>=1;j--){
		int left=0,right=j;
		while(left<right){
			if(s[left]==s[right]){
				left++;right--;
			}
			else
				break;
		}
		if(left>=right){
			ans=j+1;
			break;
		}	
	}
		

		cout<<n-ans;

	
	return 0;
}

下面的是高级的写法:

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull mod =10000;

int main() {

	string s;
	cin>>s;
	int n = s.size();
	
	ull s1 = 0,s2 = 0,ba = 1;
	int ans = 0;
	for(int i=0;i<n;i++){  //从原来序列的尾巴开始找符合回文串的长度,原长度减去这个长度就是我要补上的 
		s1 = s[i]+s1  *mod;  ///加上s[i]是为了和s中的第一个元素相同。每次就会乘mod,但是从第二次开始每个元素
		s2 = s2+  s[i]*ba; //每次乘元素分开来而已,也是从第二次开始。因为是回文。所以他们经历的次方肯定是有相同的
		ba*=mod;
		if(s1 == s2){
			ans = i+1;
		}
	}
	cout<<n-ans<<endl;
	return 0;
}

第四题 图的题目:
在这里插入图片描述
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int INF=0x3f3f3f3f;
const int N=55;
vector<pair<int,int> >e[N][2];
int vis[N],dis[2][N];
void dij(int s,int op){
    memset(vis,0,sizeof(vis));
   	memset(dis[op],INF,sizeof(dis[op]));
    dis[op][s]=0; //op 就是0 或者1  s是各种节点   x这个节点,1这个op的值是0 
    priority_queue< pair<int,int> >q;
    q.push(make_pair(-dis[op][s],s)); // 和节点相关的东西放进去  x 1  y 0,   
    while(!q.empty()){
        int u=q.top().second; // 取出这个节点 
        q.pop();
        if(vis[u]) continue; //如果这个节点走过了就跳过 
        vis[u]=1;
        int len=e[u][op].size();  //看下这个节点,op是交通方式0打车时间,1是走路时间 x 1 就是从x节点走路连接的各个节点。 
        for(int i=0;i<len;i++){
            int v=e[u][op][i].first;  //连接的节点 
            int w=e[u][op][i].second; //改节点到相应某个到节点的走路时间 或者打车的时间 
            if(dis[op][v]>dis[op][u]+w){ // 
                dis[op][v]=dis[op][u]+w;
                q.push(make_pair(-dis[op][v],v));
            }
        }
    }   
}
/// 主函数
int a[N]; 
signed main(){
    int n,m,x,y;
    cin>>n>>m>>x>>y;
    for(int i=1;i<=m;i++){
        int u,v,p,q;
        cin>>u>>v>>p>>q;
        e[u][0].push_back(make_pair(v,p)); //0代表是打车时间 
        e[v][0].push_back(make_pair(u,p));
        e[u][1].push_back(make_pair(v,q));  //1代表是走路的时间花费 
        e[v][1].push_back(make_pair(u,q));  //因为 u点到v点 等于v到u 所以都要给他弄下。   e记录了某点某种方式到达另外点的时间所有记录 
    }
    for(int i=1;i<=n;i++) cin>>a[i];  //a[i]记录了到每个站点打车的等车时间 
    dij(x,1);   //使得dis[1] 走路这个维度记录了 每个节点到x的最短时间 
    dij(y,0);   //使得dis[0] 打车这个维度记录了 每个节点到y的最短时间 
    int ans=dis[1][y];   
    for(int i=1;i<=n;i++){
        int s1=max(dis[1][i],a[i]); //1是走路 
    	ans=min(ans,s1+dis[0][i]);  //0是打车
		//是不是dis记录每个点到达终点的最短时间! 
    }
    
    ///dis[1][i]是走路的方式到达i节点花费的最短时间;
	//dis[0][i]是打车的方式从y节点到i节点花费的最短时间,所以其实两部分合起来~ 换句话说是从i节点打车到目标节点的最小值 
    cout<<dis[0][1]<<endl;
    return 0;
	}

第五题 测试专享题
题目:
输入这个员工的工资类型:N年薪制。M月薪制。 以及薪水 以及犯错类型。 L0不犯错,不扣钱,L1普通犯错,扣钱百分之2%,L2是严重犯错,扣钱百分之4.
如果是月薪制的话扣钱翻倍~~~

#include<bits/stdc++.h>
#define int long long 
using namespace std;
signed main(){
    string work,type;
    int salary;
    cin>>work;
    cin>>salary;
    cin>>type;
    unordered_map<string,int> map;
    map["L0"]=0;
    map["L1"]=2;
    map["L2"]=4;
    map["L1,L2"]=6;
    int index=1;
    if(work=="M")
        index=24;  //输出的一年扣除的? 
    
    
    int res;
    res=(index*salary*map[type])/100;
    
    cout<<res;
    
    return 0;
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值