河南萌新联赛2024第(三)场:河南大学

Circle
画出4个圈的交叉


所以就是1 2 4 8 14,从第二个数开始,每个+2,+4,+6,....以此类推。

void solve()
{
    int a[1000005]={0}; 
    a[0]=1;
    a[1]=2;
    for(int i=2;i<1000005;i++)
    {
        a[i]=a[i-1]+2*(i-1);
    }
    
    int n; cin>>n;
    while(n--)
    {
        int x; cin>>x;
        cout<<a[x]<<" ";
    }
}

keillempkill学姐の卷积
简单的模拟,但是注意细节的处理就行。

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define x first
#define y second
#define all(v) v.begin(),v.end()
#define allr(v) v.rbegin(),v.rend()
int dx[]={0,1,-1,0};
int dy[]={-1,0,0,1};

int a[25][25];
int b[25][25];
int ans[30][30];
 int n,m;
int cal(int row,int line)
{
    int temp=0;
    for(int i=row,x=1;i<row+n,x<=n;i++,x++){
        for(int j=line,y=1;j<line+n,y<=n;j++,y++)
        {
            temp+=a[x][y]*b[i][j];//注意这里a是放x,y而不是i,j
        }
    }
    return temp;
}

void solve()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++) cin>>a[i][j];
    
    for(int i=1;i<=m;i++)
        for(int j=1;j<=m;j++) cin>>b[i][j];
    
    //外面两层循环是遍历每一个点
   for(int k=1;k<=m-n+1;k++){
       for(int g=1;g<=m-n+1;g++){
    ans[k][g]=cal(k,g);
   }
   }
   
   for(int i=1;i<=m-n+1;i++){
    for(int j=1;j<=m-n+1;j++) cout<<ans[i][j]<<" ";
    cout<<endl;
   }
   
}




signed main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    int t=1; 
    //cin>>t;
    while(t--) solve();
    //cout<<ans;
    return 0;
}

SSH
多使用map来处理对应关系,边写边理清思路,有详细注释

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define x first
#define y second
#define all(v) v.begin(),v.end()
#define allr(v) v.rbegin(),v.rend()
int dx[]={0,1,-1,0};
int dy[]={-1,0,0,1};



void solve()
{
    int n,m,q; cin>>m>>n>>q;//n台主机,m个密钥对,q次查询
    map<string,string>key;//存公钥和私钥,左边si钥,右边公钥
    for(int i=0;i<m;i++)
    {
        string pub,pri;
        cin>>pub>>pri;
        key[pri]=pub;
    }
    
    map<string,set<string> >user;//存用户和对应的密钥
    map<string,set<string> >ipv4;//对应的ipv4的地址存的用户
    for(int i=0;i<n;i++)
    {
        string ip; cin>>ip;//ip
        int num;cin>>num;//有几个用户;
        while(num--)
        {
            string name; cin>>name;//用户名
            ipv4[ip].insert(name);//保存ip地址下的对应用户
            
            int cnt ;cin>>cnt;//公钥数量
            while(cnt--) {
                string keyname;//公钥名称
                cin>>keyname;
                user[name].insert(keyname);//保存用户对应的公钥
            }
        }
    }
    
    //for(auto t:user["gg"]) cout<<t<<" ";
    
    
    while(q--)
    {
        int f1=0,f2=0;
        string name ;cin>>name;
        string ip; cin>>ip;
        string keyname;cin>>keyname;//私钥
        if(ipv4[ip].find(name)!=ipv4[ip].end() ) f1=1;//用户名在对应ip的主机上
        //用户拥有该私钥对应的密钥
        string ans=key[keyname];
        if(user[name].find(ans)!=user[name].end()) f2=1;
        
        
        if(f1&&f2) cout<<"Yes";
        else cout<<"No";
        cout<<endl;
    }
    
    
}




signed main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    int t=1; 
    //cin>>t;
    while(t--) solve();
    //cout<<ans;
    return 0;
}

求值
这题可以有二分的解法,也可以有三分的解法,但是三分的细节处理挺多的,我不是很会。使用二分的解法思路这么走:

1.\(∣x∗A+y∗B+z∗C−W∣\)\(x+y+z=n\),我们可以发现\(z=n-x-y\),那么当你把z代入的时候就会有\((a-c)*x+(b-c)*y+n*c-w\),可以发现当我们枚举x,去二分y的时候,只要保证了\(b>c\),那么这个等式就可以满足单调性,所以在枚举x之前,处理b和c。

2.注意这里有一个绝对值,那么我们可以把找\(∣x∗A+y∗B+z∗C−W∣\),看成找\(x∗A+y∗B+z∗C−W>=0\)的最小值和找\(x∗A+y∗B+z∗C−W<=0\)的最大值(负数最大时,绝对值最小),都找完以后呢,再去取最小值。

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define x first
#define y second
#define all(v) v.begin(),v.end()
int dx[]={0,1,-1,0};
int dy[]={-1,0,0,1};

int a,b,c,n,w;

int cacl(int x,int y)//计算结果
{
    
    return   (a-c)*x+(b-c)*y+n*c-w;
}


void solve()
{
  
   cin>>a>>b>>c>>n>>w;
    if(b<c) swap(b,c);//保证b>c
    int ans=1e19;
    for(int i=0;i<=n;i++)//枚举x,去二分y
    {
        //找等式大于0时的最小值
        int l=0,r=n-i;
        int res=-1;
        while(l<=r) 
        {
            int mid=(l+r)>>1;//mid 相当于y,i相当于x
            if(cacl(i,mid)>=0) res=cacl(i,mid),r=mid-1;
            else l=mid+1;
        }
        
        int one=-1;
        //找等式小于0时的最大值
        l=0,r=n-i;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(cacl(i,mid)<=0){
                one=-cacl(i,mid);//要的是绝对值
                l=mid+1;
            }
            else r=mid-1;
        }
        
        if(res!=-1) ans=min(ans,res);
        if(one!=-1) ans=min(ans,one);
        
    }
    cout<<ans<<endl;
    
    
}


signed main()
{
    ios::sync_with_stdio(0),cin.tie(0);

    int t=1;
    cin>>t;
    while(t--) solve();
    return 0;
}

累加器
这一题使用ymz的超级思路:对于每一个数从0到该数的二进制位的变化数为这个数除以每个二进制位的大小,举个例子:5,从0->5,二进制位对应为0101,那么使用到的二进制位的大小为4 2 1,所以变化次数为5/1+5/2+5/4=8次,样例1:1 4,1的变化次数为1,那么答案就是8-1=7。
总结:答案就是y+x的变化次数-y的变化次数

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define x first
#define y second
#define all(v) v.begin(),v.end()
int dx[]={0,1,-1,0};
int dy[]={-1,0,0,1};

int a[35];
void ycj()
{
     a[0]=1;
    for(int i=1;i<=32;i++) a[i]=a[i-1]*2;
}


void solve()
{
    int xx,yy;cin>>xx>>yy;
    yy+=xx;
    int ans=0; 
    for(int i=0;i<=30;i++)
    {
        ans+=yy/a[i]-xx/a[i];
        
    }
    cout<<ans<<endl;
    
}


signed main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    ycj();
    int t=1;
    cin>>t;
    while(t--) solve();
    return 0;
}

热门相关:呆萌配腹黑:欢喜小冤家   我的时光里,满满都是你   我真的是正派   女王嫁到:老公,太凶了   隋唐君子演义