中大ACM个人赛 ABC题题解
摸完签到题就跑了
A - Maximum Subrectangle
题意:有个C矩阵,C[i][j] = a[i]b[j], 问你在\(\displaystyle\sum_{i=x1}^{x2}\) \(\displaystyle\sum_{j=y1}^{y2}\) \(C_{i,j}\) <= x的条件下能选出来最大子矩阵。
思路:不妨设这个子矩阵的左上角为(i,j), 右下角为(i+len1-1,j+len2-1),其中len1,len2分别代表长和宽(或宽和长)。
这个时候可以把元素和写成(a[i] + a[i+1] ... + a[i+len1-1])(b[j] + b[j+1] + ... b[j+len2-1]),这可以看成在a数组中挑出一个长度为len1的子串,在b数组中挑出一个长度为len2的子串,两者的子串和相乘。那么我们要想选出总共那么多个数的时候,各自的和尽量的小(贪心),这样才能使得相乘起来更小。比如这里的len1长度的a子串和len2长度的b子串,我要挑肯定挑各自那么长的子串中最小的。
所以问题就变成了我要在各自的数组里面先计算好长度为len时的最优解,然后遍历各自取出的长度即可。时间复杂度O(\(n^2\))。
view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 2e3+200;
const ll inf=0x3f3f3f3f3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
ll n, m;
ll a[maxn], b[maxn];
ll pre1[maxn], pre2[maxn]; //pre[i]代表子串长度为i时的最小和
ll sum1[maxn],sum2[maxn];
int main()
{
n = read(), m = read();
rep(i,1,n) a[i] = read(), sum1[i] = a[i] + sum1[i-1];
rep(i,1,m) b[i] = read(), sum2[i] = b[i] + sum2[i-1];
ll x = read();
rep(len,1,n)
{
ll mi = inf;
rep(j,len,n) mi = min(mi, sum1[j] - sum1[j-len]);
pre1[len] = mi;
}
rep(len,1,m)
{
ll mi = inf;
rep(j,len,m) mi = min(mi, sum2[j] - sum2[j-len]);
pre2[len] = mi;
}
ll ans = 0;
rep(i,1,n) rep(j,1,m)
{
if(pre1[i]*pre2[j] <= x) ans = max(ans, i*j);
}
cout<<ans<<'\n';
return 0;
}
B - Barcelonian Distance
题意:给你两个点,每步只能按照曼哈顿路径走,但是也给了你一条直线,如果在直线上就能沿着直线滑行。问你从A到B的最短路。
思路:其实不用想那么多,建边跑最短路floyd就行。一共有六个点:
1.A点。
2.A横着到直线相交的那个点。
3.A竖着到直线相交的点。
4.B点。
5.B横着交直线的点。
6.B竖着交直线的点。
这几个点先求出来然后建边,跑个floyd直接输出就好。
另外一个方法就是枚举这几种路径,就是麻烦了一点,效果一样:
1.A直接曼哈顿距离到B。
2.A沿着直线上,有两种方法,然后从直线到B,也有两种方法。
以上五种方法全写出来取最小就行。不过还是直接floyd香。
view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 1e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
double dp[20][20];
double a, b, c;
double x1, y1 , x2, y2;
typedef struct Pos
{
double x;
double y;
}P;
P point[10];
int main()
{
cin>>a>>b>>c;
cin>>x1>>y1>>x2>>y2;
rep(i,1,10) rep(j,1,10) if(i!=j) dp[i][j] = 1e18;
dp[1][6] = dp[6][1] = fabs(x1 - x2) + fabs(y1 - y2);
if(a!=0&&b!=0)
{
point[1].x = x1;
point[1].y = y1;
point[2].x = x1;
point[2].y = -(a*x1 + c)/b;
point[3].x = -(b*y1+c)/a;
point[3].y = y1;
point[4].x = x2;
point[4].y = -(a*x2 + c)/b;
point[5].x = -(b*y2+c)/a;
point[5].y = y2;
point[6].x = x2;
point[6].y = y2;
rep(i,2,5) dp[1][i] = dp[i][1] = fabs(x1 - point[i].x) + fabs(y1 - point[i].y),dp[6][i] = dp[i][6] = fabs(x2 - point[i].x) + fabs(y2 - point[i].y);
rep(i,2,5) rep(j,i+1,5) dp[i][j] = dp[j][i] = sqrt((point[i].x - point[j].x)*(point[i].x - point[j].x) +(point[i].y - point[j].y)*(point[i].y - point[j].y) );
}
rep(k,1,6) rep(i,1,6) rep(j,1,6) dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]);
printf("%f\n", dp[1][6]);
return 0;
}
C - The Unbearable Lightness of Weights
题意:找到最大的k,使得有k个相同的数组成的和m,是被唯一得到的。
思路:其实根本不太懂题目问什么。看别人博客的题意来写的。
要满足上述限制还要最优,我们的策略就是尽量挑大的k,然后我们要check一下挑k个a[i]后组成的sum是否唯一得到。
所以事先要做一遍背包,以dp[i][j]表示用j个物品凑到i重量的方案数。转移时外层用1->n个砝码去铺,内层做一个背包。转移方程为:
dp[j][k] += dp[j-a[i]][k]。
这个预处理完后就是上面说的check,我挑k个a[i],看看dp[k*a[i]][k]是否等于\(C_{Map[a[i]]}^{k}\),其中Map[a[i]]为a[i]的个数。简单排列组合问题。
最后有点疑惑的是不知道为啥种类为2的时候也能得到所有,可能还是不太理解题意吧。
view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 1e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
ll n;
ll dp[10005][105]; //dp[i][j]表示用j件物品凑到i重量的方案数
ll C[105][105];
ll a[maxn];
map<ll,ll> Map;
void init()
{
rep(i,0, 102) C[i][0] = 1;
rep(i,1,102) rep(j,1,i) C[i][j] = (C[i-1][j]+C[i-1][j-1])%mod;
}
int main()
{
init();
n = read();
ll sum = 0;
rep(i,1,n) a[i] = read(), sum += a[i], Map[a[i]]++;
dp[0][0] = 1;
rep(i,1,n) per(j,sum,a[i]) rep(k,1,i) dp[j][k] = (dp[j][k] + dp[j - a[i]][k-1]) % mod;
if(Map.size()<=2)
{
cout<<n<<'\n';
return 0;
}
ll ans = 0;
for(auto it = Map.begin(); it != Map.end(); it++)
{
ll cur = it->fi;
rep(i,1,it->se) if(dp[cur*i][i] == C[it->se][i]) ans = max(ans,i);
}
cout<<ans<<'\n';
return 0;
}
中大ACM个人赛 ABC题题解的更多相关文章
- ACM ICPC 2018 青岛赛区 部分金牌题题解(K,L,I,G)
目录: K Airdrop I Soldier Game L Sub-cycle Graph G Repair the Artwork ———————————————————— ps:楼主脑残有点严 ...
- 「浙江理工大学ACM入队200题系列」问题 L: 零基础学C/C++52——计算数列和2/1,3/2,5/3,8/5......
本题是浙江理工大学ACM入队200题第五套中的L题 我们先来看一下这题的题面. 题面 题目描述 有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13,-- 计算这个数列的前n项和.注意: ...
- Codeforces Round #519 by Botan Investments(前五题题解)
开个新号打打codeforces(以前那号玩废了),结果就遇到了这么难一套.touristD题用了map,被卡掉了(其实是对cf的评测机过分自信),G题没过, 700多行代码,码力惊人.关键是这次to ...
- AtCoder ABC 242 题解
AtCoder ABC 242 题解 A T-shirt 排名前 \(A\) 可得 T-shirt 排名 \([A+1,B]\) 中随机选 \(C\) 个得 T-shirt 给出排名 \(X\) ,求 ...
- 「浙江理工大学ACM入队200题系列」问题 L: 零基础学C/C++85——完美数
本题是浙江理工大学ACM入队200题第八套中的L题 我们先来看一下这题的题面. 题面 题目描述 任何一个自然数的约数中都有1和它本身,我们把小于它本身的因数叫做这个自然数的真约数. 如6的所有真约数是 ...
- 「浙江理工大学ACM入队200题系列」问题 K: 零基础学C/C++84——奇偶ASCII值判断
本题是浙江理工大学ACM入队200题第八套中的K题 我们先来看一下这题的题面. 题面 题目描述 任意输入一个字符,判断其ASCII是否是奇数,若是,输出YES,否则,输出NO; 例如,字符A的ASCI ...
- 「浙江理工大学ACM入队200题系列」问题 J: 零基础学C/C++83——宁宁的奥数路
本题是浙江理工大学ACM入队200题第八套中的J题 我们先来看一下这题的题面. 题面 题目描述 宁宁参加奥数班,他遇到的第一个问题是这样的:口口口+口口口=口口口,宁宁需要将1~9 九个数分别填进对应 ...
- 「浙江理工大学ACM入队200题系列」问题 E: 零基础学C/C++78——求奇数的乘积
本题是浙江理工大学ACM入队200题第八套中的E题 我们先来看一下这题的题面. 题面 输入 输入数据包含多个测试实例,每个测试实例占一行,每行的第一个数为n,表示本组数据一共有n个,接着是n个整数,你 ...
- 「浙江理工大学ACM入队200题系列」问题 F: 零基础学C/C++39——求方程的解
本题是浙江理工大学ACM入队200题第四套中的F题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...
- 「浙江理工大学ACM入队200题系列」问题 A: 零基础学C/C++34—— 3个数比较大小(冒泡排序与选择排序算法)
本题是浙江理工大学ACM入队200题第四套中的A题,同时给出了冒泡排序和选择排序算法 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习 ...
随机推荐
- MySQL建立RFM模型
1.数据来源 charge_record表数据 提取代码如下: # coding=utf-8import pymysql# 原数据库链接db1 = pymysql.connect( host='*** ...
- Mybatis的*Dao.XML中的配置与其对应的接口、resultMap的运用
例子. <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC &quo ...
- Windows 提权指南
男儿若遂平生志,五经勤向窗前读. 导航 壹 - Se 特权 贰 - RunAs 叁 - 弱服务 肆 - Windows 内核 伍 - 密码搜寻 陆 - 杂项 AlwaysInstallElevated ...
- AspNetCore 请求产生 FreeSql 所有操作 SQL 日志输出到前端
第一步:定义注入类型 public class CurdAfterLog : IDisposable { public static AsyncLocal<CurdAfterLog> Cu ...
- Quartz.Net定时任务
参照: [项目升级]集成Quartz.Net Job实现(一) - 腾讯云开发者社区-腾讯云 (tencent.com) Quartz分布式任务调度 - 掘金 (juejin.cn) 基本概念: Qu ...
- 字节大模型应用开发框架 Eino 全解(一)|结合 RAG 知识库案例分析框架生态
前言 大家好,这里是白泽,Eino 是字节开源的 Golang 大模型应用开发框架,诸如豆包.扣子等 Agent 应用或工作流都是借助这个框架进行开发. 我将通过<字节大模型应用开发框架 Ein ...
- Google Cloud Next大会上的耀眼新星:探索最具潜力的AI初创公司
在拉斯维加斯举办的Google Cloud Next大会上,不仅揭晓了如Ironwood处理器和Gemini 2.5 Flash等重磅新技术,还展示了一系列使用谷歌云计算服务的最有趣的初创公司.这些创 ...
- codeup之字符串求最大值
Description 从键盘上输入3个字符串,求出其中最大者. Input 输入3行,每行均为一个字符串. Output 一行,输入三个字符串中最大者. Sample Input Copy Engl ...
- 极简版闹钟(java)
package javaBasic; import java.awt.Toolkit; import java.awt.event.*; import java.text.SimpleDateForm ...
- Seata源码—9.Seata XA模式的事务处理
大纲 1.Seata XA分布式事务案例及AT与XA的区别 2.Seata XA分布式事务案例的各模块运行流程 3.Seata使用Spring Boot自动装配简化复杂配置 4.全局事务注解扫描组件的 ...