美团2024年春招第一场笔试【技术】

#include<bits/stdc++.h>

using namespace std;

#define int long long 
const int N=666;

int arr[N][N];
int sum[N][N];
signed main(){
	
	int n;
	while(cin>>n){
		string s;
		for(int i=0;i<n;i++){
			cin>>s;
			for(int j=1;j<=n;j++){
				if(s[j-1]=='1') arr[i+1][j]=1;
			}
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+arr[i][j];
			}
		}
//		for(int i=1;i<=n;i++){
//			for(int j=1;j<=n;j++){
//				cout<<sum[i][j]<<" ";
//			}
//			cout<<endl;
//		}
		vector<int> ans;
		ans.clear();
		for(int z=0;z<n;z++){
			int tot=0;
			if(z%2==0){
//				cout<<"z1:"<<z<<",tot:"<<0<<endl;
				ans.push_back(0);
				continue;
			} 
			int tmp=(z+1)*(z+1)/2;
			for(int i=1;i<=n;i++){
				for(int j=1;j<=n;j++){
					int x=i,y=j;
					int q=z+1;
					if((x-z>=1)&&(y-z>=1)){
						int p=sum[x][y]-sum[x-q][y]-sum[x][y-q]+sum[x-q][y-q];
//						cout<<"p tmp:"<<p<<" "<<tmp<<endl; 
						if(p==tmp){
							tot++;
						}
					}
				}
			}
//			cout<<"z2:"<<z<<",tot:"<<tot<<endl;
			ans.push_back(tot);
		}
		for(int i=0;i<ans.size();i++) cout<<ans[i]<<endl;
	}
	
	
	return 0;
} 

#include<bits/stdc++.h>

using namespace std;
#define int long long
const int N  = 2e5+100;
int arr[N];
signed main(){
	int n,q;
	while(cin>>n>>q){
		int s=0;
		int t=0;
		for(int i=1;i<=n;i++){ 
			cin>>arr[i];
			s=s+arr[i];
			if(arr[i]==0) t++;
		}
		while(q--){
			int l,r;
			cin>>l>>r;
			cout<<s+l*t<<" "<<s+r*t<<endl;
		} 
	}
	return 0;
}

#include<bits/stdc++.h>

using namespace std;
#define int long long
const int N  = 2e5 + 100;
int arr[N];
signed main() {
    int n, k;
    while (cin >> n >> k) {
        string s;
        cin >> s;
        int sum = 0;
        for (int i = 0; i < s.size(); i++) {
            if (s[i] == 'M' || s[i] == 'T') sum++;
        }
        cout << min((int)s.size(), sum + k) << endl;
    }
    return 0;
}

需要逆向构图。反向加边

#include<bits/stdc++.h>

using namespace std;
#define int long long
const int N  = 2e5+100;
int u[N],v[N];
unordered_map<int,int> f;
struct St{
	int op;
	int x,y;
}st[N];
int getf(int v){
	if(v==f[v]){
		return f[v];
	}
	f[v]=getf(f[v]);
	return f[v];
}
int merge(int u,int v){
	int t1=getf(u);
	int t2=getf(v);
	if(t1!=t2){
		f[t1]=t2;
		return 0;
	}
	return 1;
}
map<pair<int,int>,int> mp,check;
signed main(){
	int n,m,q;
	while(cin>>n>>m>>q){
		mp.clear();
		f.clear();
		check.clear();
//		for(int i=0;i<=n;i++) f[i]=i;
		for(int i=1;i<=m;i++){
			cin>>u[i]>>v[i];
			f[u[i]]=u[i],f[v[i]]=v[i];
			check[make_pair(u[i],v[i])]=1;
			check[make_pair(v[i],u[i])]=1;
		}
		for(int i=1;i<=q;i++){
			cin>>st[i].op>>st[i].x>>st[i].y;
			// 重边 
			if(st[i].op==1){
				mp[make_pair(st[i].x,st[i].y)]=1;
				mp[make_pair(st[i].y,st[i].x)]=1;				
			}

		}
		for(int i=1;i<=m;i++){
			if(mp[make_pair(u[i],v[i])]!=1){
				merge(u[i],v[i]);
			}
		}
		vector<int> ans;
		ans.clear();
		for(int i=q;i>=1;i--){
			if(st[i].op==1){
				if(check[make_pair(st[i].y,st[i].x)]||check[make_pair(st[i].x,st[i].y)])
					merge(st[i].x,st[i].y);
			}else{
				if(f.find(st[i].x)==f.end()||f.find(st[i].y)==f.end()){
					ans.push_back(0);
					continue;
				}
				int res1=getf(st[i].x);
				int res2=getf(st[i].y);
				if(res1==res2){
					ans.push_back(1);
				}else{
					ans.push_back(0);
				}
			}
		}
		reverse(ans.begin(),ans.end());
		for(auto num:ans){
			if(num) cout<<"Yes";
			else cout<<"No";
			cout<<endl;
		}
	}
	return 0;
}

这道题目我先的是计算每一个位置后面的0的个数,然后再去计算前缀和。最后通过枚举左端点,二分定位右端点得到能到达的最右的位置。但是代码写的太臭了,没过。

下面的代码借鉴2024年美团春招第一场笔试(技术)

#include<iostream>
#include<unordered_map>
#include<cmath>
using namespace std;
typedef long long LL;
const int N = 1000010;
int n,k;
int s[N];
LL sum;
 
LL c2,c5;
LL cnt2[N],cnt5[N];
 
int getNums(int x,int num)
{
	int res=0;
	
	while(x%num==0)
	{
		x/=num;
		res++;
	}
	
	return res;
}
int main()
{
	cin>>n>>k;
	
	for(int i = 1;i<=n;i++)
	{
		int x;
		cin>>x;
		cnt2[i] = getNums(x,2);
		cnt5[i] = getNums(x,5);
		c2+=cnt2[i];
		c5+=cnt5[i];
	//	cout<<cnt2[i]<<" "<<cnt5[i]<<'\n';
	}
//	cout<<c2<<" "<<c5<<'\n';
	LL res=0;
	for(int l = 1, r= 1; r<=n;r++)
	{
		c2-=cnt2[r];
		c5-=cnt5[r];
		while(min(c2,c5)<k&&l<=n)
		{
			c2+=cnt2[l];
			c5+=cnt5[l];
			l++;
		}
		if(r>=l)
		res +=r-l+1;
	}
	printf("%lld",res);
}
posted @ 2024-03-21 14:23  pengge666  阅读(72)  评论(0编辑  收藏  举报