牛客小白月赛77

牛客小白月赛77

A 小Why的方阵

思路:观察
我们很容易发现要满足题目要求只需要将对角线判断一下即可,只有有一个对角线相等,那么就是可以构成的

#include
using namespace std;
#define int long long
int mp[100];
signed main(){
    int a,b,c,d;
    cin>>a>>b>>c>>d;
    mp[a]++;
    mp[b]++;
    mp[c]++;
    mp[d]++;
    
    if((a==d)||(b==c))cout<<"YES";
    else cout<<"NO";
    
}

B 小Why的循环置换

思路:
具体证明看看官方视频,我也不好解释

#include
using namespace std;
#define int long long
signed main(){
    int n,m;cin>>n>>m;
    cout<

C 小Why的商品归位

思路:排序+贪心(正解 差分)
我想到的就是将st位置就标记为-1,ed位置标记为+1,然后遍历数组,然后维护k值即可,如果当前k为负那么就应该会重新走一遍,记录走的次数即可

#include
#define int long long
using namespace std;
const int N=1e6+7;
struct node{
    int st,en;
    bool operator <(const node &w)const{
        if(st==w.st)return en>w.en;
        else return st>n>>m>>k;
    int s=1;
    for(int i=1;i<=m;i++){
        int x,y;
        cin>>x>>y;
        tr[s++]={x,-1ll};
        tr[s++]={y,1ll};
    }
    sort(tr+1,tr+1+s);
    int ans=k,res=1;
    for(int i=1;i<=s;i++){
        ans+=tr[i].en;
        if(ans<0){
            res++;
            ans=k-1;
        }
    }
    cout<

D 小Why的密码锁

思路:字符串hash
我们将原串的hash值求一遍,然后遍历区间为m的数组求其hash值,注意我们求的hash值的同时应该维护相同hash值的先后顺序,并存入到mp中,最后遍历mp找到出现次数为k的次数

#include
using namespace std;
#define int long long
int Base1=131;
int Base2=131;
int mod1=1e9+7;
int mod2=1e9+9;
const int maxn=2e6+7;
int h1[maxn],h2[maxn],p1[maxn],p2[maxn];
signed main(){
    int n,m,k;cin>>n>>m>>k;
    string s;
    h1[0] = 0, h2[0] = 0, p1[0] = 1, p2[0] = 1;
    cin>>s;
    s="?"+s;
    for(int i=1;i<=n;i++){
        h1[i] = (h1[i-1]*Base1 + (s[i]));
       // h2[i+1] = (h2[i]*Base2 + (s[i] - '1' + 1));
    }
    for(int i = 1;i<=n;i++)
    {
        p1[i] = (p1[i-1]*Base1) ;
        //p2[i] = (p2[i-1]*Base2) ;
    }
    unordered_mapmp,last;
    for(int i=m;i<=n;i++){
        int x1=i-m+1,y1=i;
        int left1 = (h1[y1] - h1[x1-1] * p1[y1+1 - x1]);
        if(last[left1]

E 小Why的简单加减

思路:前缀和+思维
我们可以发现如果当前前缀值为负数的话,必然前面可以构成和为正数,后面必然可以根据这个负数点为基准进行题目操作,最终看能消去几个负数并加上正数

#include 
#define int long long
using namespace std;
const int N=1e6+10;
signed main(){
    int n,m;
    cin>>n>>m;
    vector a(n+1),s(n+1);
    for(int i=1;i<=n;i++){
        cin>>a[i]; s[i]=s[i-1]+a[i];
    }
    int i;
    for(i=1;i<=n;i++)if(s[i]<0)break;
    if(i<=n){//找到最小的数 作为 可以一直减的数
        int x=min_element(a.begin()+1,a.begin()+i+1)-a.begin();
        a[x]=-1e18;
    }
    int ans=0;
    vector b;
    for(int i=1;i<=n;i++)if(a[i]>=0)ans++;else b.push_back(-a[i]);
    sort(b.begin(),b.end());
    for(i=0;i=0;i++);
    cout<

F 小Why的数论测试

思路:dfs
我们可以发现如果进行一次取根号就能保证不超时,所以尽量用方案2和3跟新,然而如果当前值取根号和除以2后都不是整数的话,不是整数部分施行方案1

#include
using namespace std;
#define int long long
int dfs(int a,int b){
    if(a==b){
        return 0;
    }
    if(a>b)return 2e18;
    int res=b-a;
    res=min(res,dfs(a,b/2)+b%2+1);//通过除2
    int c=sqrt(b);
    res=min(res,dfs(a,c)+b-c*c+1);
    return res;
}
void solve(){
    int a,b;
    cin>>a>>b;
    cout<>t;
    while(t--)solve();
}

你可能感兴趣的:(算法,数据结构,c++)