2022 2-13&14

https://ac.nowcoder.com/acm/contest/28513/E

 题意:

有一个多边形的垃圾和一个通道,可以任意旋转多边形,问通道的直径最小需要多少才能让多边形通过。

 

思路:

多边形的形状是没有价值的,所以直接求出这些顶点的凸包。

然后对于凸包的每条边,求出每个点到这条边的最大距离,再求出这些最大距离中的最小距离。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define eps 1e-9
#define pi acos(-1.0)

int sgn(double d){
    if(fabs(d)<eps) return 0;
    if(d>0) return 1;
    return -1;
}

struct Point
{
    double x,y;
    Point (){}
    Point (double _x,double _y){x=_x;y=_y;}
    Point operator - (const Point &b) //直接减成 向量
    const{
        return Point(x-b.x,y-b.y);
    }
    double operator * (const Point &b) //重载运算符 俩向量 叉积
    const{
        return x*b.y-y*b.x;
    }
    double operator ^(const Point &b) //重载运算符 俩向量 点积
    const{
        return x*b.x + y*b.y;
    }
}p[111],ans[111];
int n;


bool cmp(Point a,Point b){
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}

int convex(){
    sort(p,p+n,cmp);
    int m=0;
    for(int i=0;i<n;i++){
        while(m>1&&sgn((ans[m-1]-ans[m-2])*(p[i]-ans[m-2]))==-1) m--;
        ans[m++]=p[i];
    }
    int k=m;
    for(int i=n-2;i>=0;i--){
        while(k>m&&sgn((ans[k-1]-ans[k-2])*(p[i]-ans[k-2]))==-1) k--;
        ans[k++]=p[i];
    }
    if(n>1) k--;
    return k;
}

double length(Point x1){
    return sqrt(x1^x1);
}

double dis(Point a,Point b,Point x){
    Point x1=b-a;
    Point x2=x-a;
    return abs(x1*x2/length(x1));
}

int main()
{

    while(cin>>n,n){
    for(int i=0;i<n;i++)
        cin>>p[i].x>>p[i].y;
    int mm=convex();
    double res=1e6*1.0;
    for(int i=0;i<mm;i++){
        double maxn=0;
        for(int j=0;j<mm;j++){
            if((ans[j].x==ans[i].x&&ans[i].y==ans[j].y)||(ans[j].x==ans[(i+1)%mm].x&&ans[j].y==ans[(i+1)%mm].y))
                continue;
        else{
            double an=dis(ans[i],ans[(i+1)%(mm)],ans[j]);
            maxn=max(an,maxn);
            }
        }res=min(res,maxn);
    }
    printf("%.9lf\n",res);
    }
    return 0;
}

 

https://ac.nowcoder.com/acm/contest/28513/F

题意:

有一个N边形的车,车速为v,你在原点,你的速度为u,想要到达(0,w),问人最快到达(0,w)点的时间。显然,车如果挡住你,你就不能走。

 

思路:

你走过去的情况就分两种:车对你没造成影响,车对你造成影响。

当车对你没造成影响又分两种情况:你的速度太快了,车的速度太快了。

分析这些情况
                      1:你的速度太快了。车的任意一点都到达不了你的位置。既 xi/v>yi/u。

                      2:车的速度太快了,你到达 车任意一点在y轴的投影时,车已经过去了。既xi/v<yi/u.

                      3:车对你造成影响,此时你需要调整速度来躲车,我们可以换一种角度看,当车最后一个点通过的时候,你在内个点上,
                      
                      此时需要的时间就是车走xi 速度为v所需要的时间,再后面的路程(w-yi),你以速度u走。

 

https://www.luogu.com.cn/problem/P1045

高精度快速幂

本题P<=3100000,所以不能去对整个数进行乘法运算.

于是我们可以直接对后五百位进行计算,并用压位高精和快速幂优化;

代码:

#include <bits/stdc++.h>
using namespace std;
int f[1001],p,res[1001],sav[1001],s;//sav[]是暂存计算过程的结果的数组
void result_1(){
	memset(sav,0,sizeof(sav));
	for(int i=1;i<=500;i++)//乘法无倒正
	    for(int j=1;j<=500;j++) sav[i+j-1]+=res[i]*f[j];
	for(int i=1;i<=1000;i++){//处理进位
		sav[i+1]+=sav[i]/10;
		sav[i]=sav[i]%10;
	}
	for(int i=0;i<=1000;i++) res[i]=sav[i]; //存储结果
 }
void result_2(){
	memset(sav,0,sizeof(sav));
	for(int i=1;i<=500;i++)//循环到500即可,不用到1000
	    for(int j=1;j<=500;j++) sav[i+j-1]+=f[i]*f[j];//乘法无倒正
	for(int i=1;i<=1000;i++){
		sav[i+1]+=sav[i]/10;
		sav[i]=sav[i]%10;
	}
	for(int i=0;i<=1000;i++) f[i]=sav[i];//存储结果
 }
int main(){
	cin>>p;
	s=(int)(log10(2)*p)+1;//log10是自带函数
	res[1]=1;//初始化应该是1
	f[1]=2;//重要初始化 f[]是2的p次方的结果,初始化应该是2而不是1
	cout<<s<<endl;
	while(p) {//计算2的p次方
		if(p&1) result_1();
		p>>=1;
		result_2();
	}
	res[1]-=1;//2的p次方-1
	for(int i=500;i>=1;i--){
        if(i!=500&&i%50==0) cout<<endl;
	    	cout<<res[i];
		 }
	return 0;
}

 

https://codeforces.com/contest/1637/problem/E

 题意:

给长度为n的数组
 计算俩不同数字 出现的次数和*俩数字之和 最大值
 
 x出现 cntx次 ; y出现cnty次
 ans=max(ans,(cnts+cnty)*(x+y));

思路:

用map记录数组每个数x出现次数c

用vector<>o[] 存储相同次数c的数x(v[c].push(x)) 并对v[c]内元素由大到小存储

用vector<pair<>>b 存储特殊快

遍历o[]时 用二分函数判断b是否含有

代码:

#include <bits/stdc++.h>
using namespace std;

void solve() {
    int n, m;
    cin >> n >> m;
    map<int, int> cnt;
    for (int i=0;i<n;i++) {
        int x;
        cin>>x;
        cnt[x]++;
    }
    vector<pair<int, int>> b;
    for (int i = 0; i < m; i++) {
        int x, y;
        cin >>x>>y;
        b.emplace_back(x, y);
        b.emplace_back(y, x);
    }
    sort(b.begin(), b.end());

    vector<long long> o[n];
    for (auto &[x,c]:cnt)
        o[c].push_back(x);

    for (auto &v : o)
        reverse(v.begin(),v.end());

    long long ans= 0;
    for (int cnt_x = 1; cnt_x < n; cnt_x++)
        for (int x : o[cnt_x])
            for (int cnt_y = 1; cnt_y <= cnt_x; cnt_y++)
                for (auto y : o[cnt_y])
                    if (x != y && !binary_search(b.begin(), b.end(), pair<int, int>{x, y})) {
                        ans= max(ans, 1ll * (cnt_x + cnt_y) * (x + y));
                        break;
                    }

    cout << ans << '\n';
}

int main() {

    int t;
    cin >> t;
    while (t--)
        solve();
}

 

https://codeforces.com/contest/1637/problem/D

思路:

对于一个位置i上的值x的贡献为自身平方的n-1倍和自身与其他数进行乘积的2倍之和

假设有四个数a,b,c,d;

贡献: (n-1)*(a*a+b*b+c*c+d*d)+(2ab+2ac+2ad+2bc+2bd+2cd)
     =(n-2)*(a*a+b*b+c*c+d*d)+a*(a+b+c+d)+b*(a+b+c+d)+c*(a+b+c+d)+d*(a+b+c+d)
     =(n-2)*(a*a+b*b+c*c+d*d)+(a+b+c+d)*(a+b+c+d)

代码:

#include <iostream>
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[111],b[111];
int n;
 int dp[111][10005];
int main()
{
    int T;
    cin>>T;
    while(T--){
    memset(dp,0,sizeof(dp));
     int n;
     cin>>n;
     ll ans=0;
     for(int i=0;i<n;i++) cin>>a[i],ans+=(a[i]*a[i]);
     for(int i=0;i<n;i++) cin>>b[i],ans+=(b[i]*b[i]);
     ans=(n-2)*ans;
     ll sum=0,su=0;
     for(int i=0;i<n;i++)
        sum+=max(a[i],b[i]),su+=a[i]+b[i];
     dp[0][a[0]]=1,dp[0][b[0]]=1;
     for(int i=1;i<n;i++){
        for(int j=0;j<=sum+5;j++){
            if(dp[i-1][j])
                dp[i][j+a[i]]=1,dp[i][j+b[i]]=1;//前i个数 a数组的可能值j
        }
     }
     ll res=1e9;
     for(int i=0;i<=sum+5;i++)
        if(dp[n-1][i])
        res=min(res,i*i+(su-i)*(su-i)); //遍历

    cout<<res+ans<<endl;
    }
    return 0;
}

 

posted @   GGood_Name  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示