目录
D. Balanced Round
E. Cardboard for Pictures
F. We Were Both Children
G. The Morning Star
H. The Third Letter
题意:给定数组,可以从中删去一定的数字,要求删去后的数组任意两数之间的绝对值之差不大于k。
思路:题目要我们先删除,但先排序后删除本质上是一样的,所以先将数组进行排序,由此,此题转话为了在有序数组中寻找最大的一段符合条件的的区间,即区间中后一个数减前一个的差不能超过k,因为题目要求剩余区间全部合法,所以我们只用求出最大合法区间,然后把其他的全部删去就好。
#include
using namespace std;
const int N=1e5+5;
typedef long long ll;
typedef pair pll;
int mod=998244353;
const int maxv=4e6+5;
ll qmi(int a,int b)
{
ll res=1;
while(b){
if(b%2) res*=b%mod;
b>>=1;
a=a*a%mod;
}
return res;
}
ll inv(int x)
{
return qmi(x,mod-2);
}
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
void solve()
{
int n,k;
cin>>n>>k;
vector a(n+5);
for(int i=1;i<=n;i++) cin>>a[i];
sort(a.begin()+1,a.begin()+1+n);
int cnt=1;
int res=0;
for(int i=1;i>t;
while(t--){
solve();
}
system("pause");
return 0;
}
题意,给定总面积s,然后给定每个正方形的面积,现给每个正方形的外圈裱一层w长的外圈,求让所有正方形裱完后的面积总和等于s的w。
思路:题意被我描述的可能有点抽象,但思路就是去二分答案,容易知道,w是具有单调性的,即w越大,最后的面积总和也一定越大,所有可以去二分去解决。
#include
using namespace std;
const int N=2e5+5;
typedef long long ll;
typedef pair pll;
int mod=998244353;
const int maxv=4e6+5;
ll qmi(int a,int b)
{
ll res=1;
while(b){
if(b%2) res*=b%mod;
b>>=1;
a=a*a%mod;
}
return res;
}
ll inv(int x)
{
return qmi(x,mod-2);
}
ll n,c;
vector s(N);
bool check(ll x)
{
ll sum=0;
for(int i=1;i<=n;i++){
ll m=(s[i]+x*2)*(s[i]+x*2);
sum+=m;
if(sum>c) return false;
}
return true;
}
void solve()
{
cin>>n>>c;
for(int i=1;i<=n;i++) cin>>s[i];
ll l=0,r=1e9;
ll ans=0;
while(l<=r){
ll mid=(l+r)/2;
if(check(mid)){
l=mid+1;
ans=mid;
}
else{
r=mid-1;
}
}
cout<>t;
while(t--){
solve();
}
system("pause");
return 0;
}
题意:给定数组,让我们求1-n中的某个数,为数组中某些数字的倍数,且数组元素个数最大。
思路:一开始初看题意以为考察的是lcm,结果一细想是分解因数。一开始考虑的是数组中每个元素因子在数组中的出现次数,后面再细想应该是求1-n中的每个数字的因子在数组中的出现次数。
#include
using namespace std;
const int N=2e5+5;
typedef long long ll;
typedef pair pll;
int mod=998244353;
const int maxv=4e6+5;
ll qmi(int a,int b)
{
ll res=1;
while(b){
if(b%2) res*=b%mod;
b>>=1;
a=a*a%mod;
}
return res;
}
ll inv(int x)
{
return qmi(x,mod-2);
}
void solve()
{
int n;
cin>>n;
map mp;
for(int i=1;i<=n;i++){
int x;
cin>>x;
mp[x]++;
}
int ans =0;
for(int j=1;j<=n;j++){
int res=0;
for(int i=1;i<=j/i;i++){
if(j%i==0){
int c1=j/i;
res+=mp[c1];
if(i!=j/i) res+=mp[i];
}
}
ans=max(ans,res);
}
cout<>t;
while(t--){
solve();
}
system("pause");
return 0;
}
题意:给定n个坐标,要求求出符合题意坐标对的数量。
思路:就是和斜率有关的表示吧,开个map存一下x,y,x+y,x-y这四种情况,然后遍历相加即可。
#include
using namespace std;
const int N=2e5+5;
typedef long long ll;
typedef pair pll;
int mod=998244353;
const int maxv=4e6+5;
ll qmi(int a,int b)
{
ll res=1;
while(b){
if(b%2) res*=b%mod;
b>>=1;
a=a*a%mod;
}
return res;
}
ll inv(int x)
{
return qmi(x,mod-2);
}
void solve()
{
int n;
cin>>n;
vector a(n),b(n);
map x,y,kz,kf;
for(int i=0;i>a[i]>>b[i];
x[a[i]]++;
y[b[i]]++;
ll c1=a[i]-b[i];
ll c2=a[i]+b[i];
ll x=qmi(c1,c2);
kz[c1]++;
kf[c2]++;
}
ll ans =0;
for(int i=0;i>t;
while(t--){
solve();
}
system("pause");
return 0;
}
题意:给定n个点,m条边,要求判断建成的图是否合法
思路:先建图,然后再去遍历bfs判断是否合法即可。
#include
using namespace std;
const int N=2e5+5;
typedef long long ll;
typedef pair pll;
int mod=998244353;
const int maxv=4e6+5;
ll qmi(int a,int b)
{
ll res=1;
while(b){
if(b%2) res*=b%mod;
b>>=1;
a=a*a%mod;
}
return res;
}
ll inv(int x)
{
return qmi(x,mod-2);
}
ll d[N];
int st[N];
vector e[N];
void add(int a,int b,int w)
{
e[a].push_back({b,w});
}
const ll inf=10000000000;
void solve()
{
int n,m;
cin>>n>>m;
fill(d,d+n+1,inf);
for(int i=1;i<=n;i++) e[i].clear();
for(int i=1;i<=m;i++){
int a,b,w;
cin>>a>>b>>w;
add(a,b,w);//建图
add(b,a,-w);//无向边要减2条,注意反向的权值
}
for(int i=1;i<=n;i++){
if(d[i]!=inf) continue;//di不等于inf则表示当前已经遍历过该点了
queue q;
q.push(i);//不然的话为一个新的连通块
d[i]=0;//赋值为0
while(!q.empty()){//bfs遍历过程
int t=q.front();
q.pop();
for(auto [x,y]: e[t]){
if(d[x]==inf){//如果当前点还没有被遍历到,就更新当前点的距离
d[x]=d[t]+y;
q.push(x);
}
else{
if(d[x]!=y+d[t]){//不然的话就去判断当前点的距离是否合法
cout<<"NO"<>t;
while(t--){
solve();
}
system("pause");
return 0;
}