美团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);
}