暑假学习记录8.14

92 篇文章 0 订阅

牛客 生日快乐

        n<=10所以直接暴力切即可,对于每一刀,切的必须是x/n或者y/n的倍数,这样才能保证切n刀之后每块面积都相等,所以直接考虑每一刀对长切或者对宽切,对于每次的两种切法取最小值。假设对长切,那么就枚举从1到要切的块数除二的倍数i,该次切除的x就是i∗x/n,切出的另一块是x−i∗x/n,直到切到n=1为止,不需要再切了,计算长比宽,然后对这些块取最大值,然后考虑切宽的情况,和上面同理。切长和切宽之间取最小值即可(看的题解。。。https://blog.nowcoder.net/n/fe503123323d41598d8626f9a3817328?f=comment)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
#include<iomanip>
#include<map>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<list>
#include<stack>
#include<set>
#include<ctime>
#define ll long long
#define CHECK(x,y) (x>=0&&x<n&&y>=0&&y<n&&a[x][y]=='#')
//#include<bits/stdc++.h>
using namespace std;
const ll maxx=1e9;
int dir[4][3]={
            {-1,0},
            {1,0},
            {0,-1},
            {0,1},
     };
int n;double X,Y;
double dfs(double x,double y,int t){
   // cout<<"Yes"<<endl;
    if(t==1) return max(x,y)/min(x,y);
    double ans=1e9,h,w,a=x/t,b=y/t;//对于每一刀,切的必须是x/n或者y/n的倍数,这样才能保证切n刀之后每块面积都相等
    for(int i=1;i<=t/2;i++){
        h=max(dfs(i*a,y,i),dfs(x-i*a,y,t-i));
        w=max(dfs(x,i*b,i),dfs(x,y-i*b,t-i));
        ans=min(ans,min(h,w));
    }
    return ans;
    }
int main(){
    //   freopen("in.txt","r",stdin);
cin>>X>>Y>>n;
printf("%.6f\n",dfs(X,Y,n));
return 0;
}

牛客 ZJH and Monkeys

        这道题同样还是没有像出思路来,卡在了求点与点的距离上,看了题解知道了有一个方法求1到其他点的距离即可,而且求距离的方法也挺好Orz

大佬的思路:①:如果n是奇数的话,只能是偶+奇+偶 或 奇+偶+奇或者 奇,偶,偶 或者,偶奇奇    

所以就是    ans=oushu*jishu*oushu*2;

                  ans+=jishu*oushu*jishu*2;

②:如果n是偶数的话,只能是偶偶奇,偶偶偶,奇奇奇, 奇奇偶  

  所以就是    ans+=(jishu*jishu+oushu*oushu)*n

    因为  偶偶奇+偶偶偶=(偶偶)所有

所以我们就只需要找出根节点1到其他点的距离就好了,利用dfs求深度。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
#include<iomanip>
#include<map>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<list>
#include<stack>
#include<set>
#include<ctime>
#define ll long long
#define CHECK(x,y) (x>=0&&x<n&&y>=0&&y<n&&a[x][y]=='#')
//#include<bits/stdc++.h>
using namespace std;
const ll maxx=1e9;
int dir[4][3]={
            {-1,0},
            {1,0},
            {0,-1},
            {0,1},
     };
int n,dis[100010];
ll ans,even,odd;
vector<int>a[100010];
void dfs(int u,int v,int cnt){//利用递归求距离——未曾设想的道路
    dis[u]=cnt;
    for(int i=0;i<a[u].size();i++){
        int d=a[u][i];
        if(d==v) continue;
        dfs(d,u,cnt+1);
    }
    return;
    }
int main(){
  //   freopen("in.txt","r",stdin);
    int t;
    cin>>t;
    while(t--){
        int u,v;
        for(int i=0;i<=n;i++) a[i].clear();
        cin>>n;
        for(int i=1;i<n;i++){
            cin>>u>>v;
            a[u].push_back(v);
            a[v].push_back(u);
        }
        dfs(1,1,1);
        odd=0;even=0;
        for(int i=1;i<=n;i++){
            if(dis[i]%2==0)
                even++;
            else odd++;
        }
        ans=0;
        if(n%2==1){
                        ans=even*odd*even*2;
            ans+=odd*even*odd*2;
        }
        else{
            ans+=(odd*odd+even*even)*n;
        }
            printf("%d\n",ans);
    }
return 0;
}

牛客 轰炸区最优选取

        能用前缀和做出来,原理还不是很懂,只知道这样做是对的。。。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
#include<iomanip>
#include<map>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<list>
#include<stack>
#include<set>
#include<ctime>
#define ll long long
#define CHECK(x,y) (x>=0&&x<n&&y>=0&&y<n&&a[x][y]=='#')
//#include<bits/stdc++.h>
using namespace std;
const ll maxx=1e9;
int dir[4][3]={
            {-1,0},
            {1,0},
            {0,-1},
            {0,1},
     };
int n,k;
int a[55][55],ans=0;
/*void dfs(int x,int y,int orix,int oriy,int cnt){
    if(x-orix+1==k&&y-oriy==k) {ans=max(ans,cnt);return;}
    if(x-orix+1>k||y-oriy+1>k) return;
    return dfs(x+1,y,orix,oriy,cnt+a[x+1][y]);
    return dfs(x,y+1,orix,oriy,cnt+a[x][y+1]);
    }*/
int main(){
   //  freopen("in.txt","r",stdin);
    while(scanf("%d%d",&n,&k)!=EOF){
        for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            scanf("%d",&a[i][j]);
            a[i][j]=a[i][j]+a[i-1][j]+a[i][j-1]-a[i-1][j-1];
        }
    }
     ans=0;
    for(int i=k;i<=n;i++){
        for(int j=k;j<=n;j++){
            ans=max(ans,a[i][j]-a[i-k][j]-a[i][j-k]+a[i-k][j-k]);
        }
    }
    cout<<ans<<endl;
    }
    
return 0;
}

        还有一个笨方法,就是把所有的矩阵都求出来,我当时以为这样做会超时(会涉及四重循环)就没敢作,结果还真可以。。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
#include<iomanip>
#include<map>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<list>
#include<stack>
#include<set>
#include<ctime>
#define ll long long
#define CHECK(x,y) (x>=0&&x<n&&y>=0&&y<n&&a[x][y]=='#')
//#include<bits/stdc++.h>
using namespace std;
const ll maxx=1e9;
int dir[4][3]={
            {-1,0},
            {1,0},
            {0,-1},
            {0,1},
     };
int n,k;
int a[55][55],ans=0;
void dfs(int x,int y,int orix,int oriy,int cnt){
    if(x-orix+1==k&&y-oriy==k) {ans=max(ans,cnt);return;}
    if(x-orix+1>k||y-oriy+1>k) return;
    return dfs(x+1,y,orix,oriy,cnt+a[x+1][y]);
    return dfs(x,y+1,orix,oriy,cnt+a[x][y+1]);
    }
int main(){
   //  freopen("in.txt","r",stdin);
    while(scanf("%d%d",&n,&k)!=EOF){
        for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            scanf("%d",&a[i][j]);
            a[i][j]=a[i][j]+a[i-1][j]+a[i][j-1]-a[i-1][j-1];
        }
    }
     ans=0;
    for(int i=k;i<=n;i++){
        for(int j=k;j<=n;j++){
            ans=max(ans,a[i][j]-a[i-k][j]-a[i][j-k]+a[i-k][j-k]);
        }
    }
    cout<<ans<<endl;
    }
    
return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

killer_queen4804

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值