• AGC 016 C


    题面在这里!

        结合了贪心的构造真是妙啊2333

        一开始推式子发现 权是被多少个w*h矩形覆盖到的时候 带权和 <0 ,权都是1的时候带权和 >0,也就是说被矩形覆盖的多的我们要让它尽量小。

        但这个好像并没有什么乱用的样子QWQ,不过这却引导出了我的第一个想法:能否选出尽量少的特殊点使得他们等于 -w*h,而其他不是特殊点的位置等于1,并且每个w*h的矩阵都包含至少一个特殊点。

        再想一想发现让 i%w==0 且 j%h==0 的点 (i,j) 作为特殊点是最优的了(可能有相同效果的方案但是没有更优的了).

        于是先这么填然后看最后的总和是否>0输出答案。。。

        果断的交了一发,于是WA了    QWQ

        那么问题出在哪里呢?

        主要是没有动手算。

        于是便有了代码注释上的正解QWQ  (这里补充一下代码注释里的原理,如果y=1的话那么后面那个-1占的权重太大了很可能会使结果<=0,让y变大就相当于让-1的绝对值减小,使得 y - 1/w/h 与 y 的相对差尽量小,小到可以忽略的时候就是正解啦) 

    // n/w * m/h 个特殊点
    // 设特殊点权值为x,其他点为y,那么满足:
    // x + y *(w*h-1) < 0   =>  x = y * (1 - w*h) - 1
    // n/w * m/h * (x-y) + y * n * m > 0 
    
    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=505;
    
    int a[N][N],n,m,w,h,v;
    ll sum=0;
    
    int main(){
    	scanf("%d%d%d%d",&n,&m,&w,&h),v=1000*(1-w*h)-1;
    	for(int i=w;i<=n;i+=w)
    		for(int j=h;j<=m;j+=h) a[i][j]=v;
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    		    if(a[i][j]) sum+=(ll)a[i][j];
    	        else sum+=(ll)1000,a[i][j]+=1000;
    
    	if(sum<=0){ puts("No"); return 0;}
    
    	puts("Yes");
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++) printf("%d ",a[i][j]);
    		puts("");
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    Java导出Excel和CSV(简单Demo)
    ffmepg命令行参数
    VLC命令参数(转载)
    深入Java虚拟机读书笔记第五章Java虚拟机
    JS常用方法记录
    记一次数据库的优化
    Infobright数据库使用
    Mysql连接驱动8.0版本改动
    Eclipse新建SrpingBoot项目Pom.xml文件报错
    SpringBoot 热部署开发
  • 原文地址:https://www.cnblogs.com/JYYHH/p/9295721.html
Copyright © 2020-2023  润新知