20160730noip模拟赛zld

codeforces394E

如果没有在凸多边形内一点的限制,答案肯定是

如果不在凸多边形内,那么目标点肯定在凸多边形边上,我们枚举每条边,在每条边上求出距离平方和最小的点,在这些点中求出最小的

我们可以发现固定一点计算这个平方和不要O(m)的时间,只要维护x坐标平方和,x坐标的和就可以O(1)计算,但是计算起来很鬼畜

其实最后答案就是凸多边形上,离这个最近的点。

#include<map>
#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<complex>
#include<iostream>
#include<assert.h>
#include<algorithm>
using namespace std;
#define inf 1001001001
#define infll 1001001001001001001LL
#define FOR0(i,n) for(int (i)=0;(i)<(n);++(i))
#define FOR1(i,n) for(int (i)=1;(i)<=(n);++(i))
#define ll long long
#define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl
#define gmax(a,b) (a)=max((a),(b))
#define gmin(a,b) (a)=min((a),(b))
#define ios0 ios_base::sync_with_stdio(0)
#define Ri register int
#define gc getchar()
#define il inline
il int read(){
    bool f=true;
    Ri x=0;char ch;
    while(!isdigit(ch=gc))if(ch==‘-‘)f=false;
    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-‘0‘;ch=gc;}
    return f?x:-x;
}
#define gi read()
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
int n,m;
#define eps 1e-6
struct point{
    double x,y;
    il void rd(){
        x=gi;y=gi;
    }
    point operator+(point a) {return (point){x+a.x,y+a.y};}
    point operator-(point a) {return (point){x-a.x,y-a.y};}
    point operator*(double a){return (point){x*a,y*a};}
    point operator/(double a){return (point){x/a,y/a};}
    double operator^(point a){return x*a.y-y*a.x;}//叉积
    double operator&(point a){return x*a.x+y*a.y;}//点积
}p[100001],q[100001];
//q m个点的 多边形
//p n个目标点
double A,B,C;
bool inside(point a,point b,point c){//chk if a between b-c
    double A=a-b&c-b;
    double B=c-b&c-b;
    double C=a-b^c-b;
    if (fabs(C)>eps) return 0;
    if (A>-eps&&A<B+eps) return 1;
    return 0;
}
int in_hull(point *b,point q) {
    int cnt=0;
    FOR1(i,m){
        if(inside(q,b[i],b[i+1]))    return 2;
        if((b[i]-q^b[i+1]-q)>eps)    cnt++;
    }
    if (cnt==m||!cnt) return 1;
    return 0;
}
double dist(point a,point b){
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
int main(){
    FO(point);
    n=gi;
    FOR1(i,n)p[i].rd();
    m=gi;
    FOR1(i,m)q[i].rd();q[0]=q[m];
    double sx,sy,sx2,sy2;sx=sy=sx2=sy2=0;
    FOR1(i,n)sx+=p[i].x,sy+=p[i].y,sx2+=p[i].x*p[i].x,sy2+=p[i].y*p[i].y ;
    if(in_hull(q,(point){sx/n,sy/n})){
        double ans=0.0;
        FOR1(i,n)ans+=dist((point){sx/n,sy/n},p[i]);
        printf("%.8lf",ans);
        //做到这里发现不会算不在多边形内的
    }else{
        sx*=2.0;sy*=2.0;
        double ans=infll;
        for(int i=0;i<m;i++){
            int s=i,t=i+1;
            double dx=q[t].x-q[s].x,dy=q[t].y-q[s].y;
            double a=q[s].x,b=q[s].y;
            double A=dx*dx+dy*dy,B=2*a*dx+2*b*dy-sx/n*dx-sy/n*dy;
            double k=(-B)/(2*A);
            if(k<0) k=0;
            if(k>1) k=1;
            double x=a+dx*k,y=b+dy*k;
            double ss=n*(x-sx/(2.0*n))*(x-sx/(2.0*n))+sx2-(sx*sx)/(4.0*n)+n*(y-sy/(2.0*n))*(y-sy/(2.0*n))+sy2-(sy*sy)/(4.0*n);
            ans=min(ans,ss);
        }
        printf("%.8lf\n",ans);
    }
    //30/07/16 09:38如果WA了就是哪里nm pq反了
    //30/07/16 09:52写完发现推的不对
    //
    return 0;
}

套用一位大佬的话,这是一道送命题

题目要求相当于是使每一行都与第一行相等或者完全相反

那么就大概有了思路

当n>k时。肯定有没被修改的行,我们枚举这个行在哪

当n<=k时,枚举第一列的状态,统计答案

#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<complex>
#include<iostream>
#include<assert.h>
#include<algorithm>
using namespace std;
#define inf 1001001001
#define infll 1001001001001001001LL
#define FOR0(i,n) for(int (i)=0;(i)<(n);++(i))
#define FOR1(i,n) for(int (i)=1;(i)<=(n);++(i))
#define ll long long
#define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl
#define gmax(a,b) (a)=max((a),(b))
#define gmin(a,b) (a)=min((a),(b))
#define ios0 ios_base::sync_with_stdio(0)
#define Ri register int
#define gc getchar()
#define il inline
il int read(){
    bool f=true;
    Ri x=0;char ch;
    while(!isdigit(ch=gc))if(ch==‘-‘)f=false;
    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-‘0‘;ch=gc;}
    return f?x:-x;
}
#define gi read()
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
int n,m,k,map[101][101];

int main(){
    FO(table);
    int T=gi;
    while(T--){
        n=gi;m=gi;k=gi;
        FOR1(i,n)FOR1(j,m)map[i][j]=gi;
        if(n>k){
            int res=inf,ans;
            FOR1(i,n){
                ans=0;
                FOR1(j,n){
                    int cnt=0;
                    if(i!=j)
                        FOR1(k,m){
                            cnt+=map[i][k]^map[j][k];
                        }
                    ans+=min(cnt,m-cnt);
                }
                gmin(res,ans);
            }
            printf("%d\n",res>k?-1:res);
        }else{
            bool p[101];int ans=inf;
            FOR0(st,1<<n){
                FOR1(i,n)p[i]=st&(1<<(i-1));
//                FOR1(i,n)cout<<p[i];puts("");
                int res=0;
                FOR1(i,n)res+=(p[i]^map[i][1]);
                FOR1(i,m){
                    int cnt=0;
                    FOR1(j,n)cnt+=(p[j]^map[j][i]);
                    res+=min(cnt,n-cnt);
                }
//                cout<<res<<endl;
                gmin(ans,res);
            }
            printf("%d\n",ans>k?-1:ans);
        }
//        puts("----------------------------");
    }
    return 0;
}

T3

还没做

时间: 2024-10-16 03:29:19

20160730noip模拟赛zld的相关文章

20160727noip模拟赛zld

首先最优策略肯定是这样的:我们取出这个序列中的最大值,然后将整个序列分为左右两部分, 那么我们一定先把左右两部分合起来然后再与这个值合并 那么我们可以得出一个基于最值查询(rmq)的的算法,但是zld上次出10^6级别的题目时,卡掉了的算法 所以我们想一个优秀一点的做法,发现这个过程可以简单的用一个单调队列维护,维护单调减的单调栈,就可以O(n)解决这个问题 我们仔细观察会发现更优秀的做法,答案一定是,但是这个玩意我不会证明 int a[2333333]; int main(){ FO(seq)

20160731noip模拟赛zld

首先显然有多少个奇数,就有多少个回文串是最优的(没有奇数时构造一个回文串 然后有了k个"核心",把剩下的字符顺序安排到这些的两侧,最后最短的回文串长度就是答案 #include<map> #include<stack> #include<queue> #include<cstdio> #include<string> #include<vector> #include<cstring> #include

【BZOJ】【2741】【FOTILE模拟赛】L

可持久化Trie+分块 神题……Orz zyf & lyd 首先我们先将整个序列搞个前缀异或和,那么某一段的异或和,就变成了两个数的异或和,所以我们就将询问[某个区间中最大的区间异或和]改变成[某个区间中 max(两个数的异或和)] 要是我们能将所有[l,r]的答案都预处理出来,那么我们就可以O(1)回答了:然而我们并不能. 一个常见的折中方案:分块! 这里先假设我们实现了一个神奇的函数ask(l,r,x),可以帮我们求出[l,r]这个区间中的数,与x最大的异或值. 我们不预处理所有的左端点,我

10.30 NFLS-NOIP模拟赛 解题报告

总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没码QAQ 现在我来写解题报告了,有点饿了QAQ.. 第一题 题目 1: 架设电话线 [Jeffrey Wang, 2007] 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务,于 是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线.新的电话线架设 在已有的N(2 <=

bzoj 2741: 【FOTILE模拟赛】L 分塊+可持久化trie

2741: [FOTILE模拟赛]L Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1116  Solved: 292[Submit][Status] Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 ... xor Aj),其中l<=i<=j<=r. 为了体现在线操作,对于一个询问(x,y):

9.14 模拟赛

模拟赛第三弹~ T1 题意:给你一个数列,要求删掉任意一种整数,使得剩下的新数列中连续的相等的数最多 例如 2 7 3 7 7 3 3 7 7 5 7,删掉3以后剩的7有四个连续的,最多 思路:暴力枚举去掉哪个......这算是一道水题吧 代码丢了...... TAT T2 题意:有n本书,每本书有宽度和高度.现在你有无数个书架,每个书架的宽度为w,高度由最高的书决定 问在书本按顺序放的情况下,总的书架高度最小是多少 思路:dp,dp[i]表示做到第i本书时的最小高度和. 每次先找到能以编号j的

2014-9-9 NOIP模拟赛

东方幻想乡系列模拟赛Stage 1命题 Nettle审题 Barty ccy1991911 FlanS39 Wagner T2 高精除高精,从来没写过,不知道怎么写,我就用大数减小数ans次,果断超时. T4 Tarjan的板子题,好久没写,中间出现了一些小错误 ①是尽管有双向边,Tarjan函数中也不必排除双向边 ②Tarjan算法有时候不能一步完成,需要做最多n次,用循环解决 ③问题是关于这个题目的虽然输入n代表有n个点,但是下面的连边中有些点根本没出现过,所以设一个数组记录有效点. Pro

【题解】PAT团体程序设计天梯赛 - 模拟赛

由于本人愚笨,最后一题实在无力AC,于是只有前14题的题解Orz 总的来说,这次模拟赛的题目不算难,前14题基本上一眼就有思路,但是某些题写起来确实不太容易,编码复杂度有点高~ L1-1 N个数求和 设计一个分数类,重载加法运算符,注意要约分,用欧几里得算法求个最大公约数即可. 1 #include <cstdio> 2 3 long long abs(long long x) 4 { 5 return x < 0 ? -x : x; 6 } 7 8 long long gcd(long

20161027模拟赛解题报告

20161027模拟赛解题报告 By shenben T1 数学题 模拟即可. 注意开long long T2 技巧题 图片为本题第一张图.(无奈,图传不上来) 首先第一问图中的“Y 字形”的数量,这么简单,在此不细讲. 详见代码 O(n)累加一下就好了 主要说说第二问怎么搞 预处理 每个点分别与其他那些点相连 权值为第1,2,3大(若没有2,3大,就忽略).记录一下权值与对应的点的标号.目的是方便下面的判断. 枚举入度>=3的点,即点B(有多个) 再枚举点B相连的D点(不是点A,C). Ste