G-鸡格线 (set+二分)
G-鸡格线_2023牛客寒假算法基础集训营1 (nowcoder.com)
思路:
通过观察可以发现,在经过一定次数的操作后(小于20次),该数再经过操作就不会改变从而固定,如:
0 -> 0
1-99 ->10
100-1e9 ->100
所以可以用set储存输入的数组中操作之后会改变的值的下标,并记录初始的总和。对于每次对 [l ,r]中的数值操作k次,我们在set中二分出大于等于 l 的第一个下标,对该下标的值操作 min(k,20) 次,直至该下标大于 r 结束。 每次操作的同时修改sum的值即可。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int a[N];
int n,m;
int f(int x){
return round(10*sqrt(x));
}
void solve(){
cin >> n >> m;
set<int> st;
int sum=0;
for(int i=1;i<=n;i++){
cin >> a[i];
sum+=a[i];
if(a[i]!=f(a[i])){
st.insert(i); //该坐标上的值还要修改,存进去
}
}
st.insert(n+1); //插入n+1下标保证下面必定能break
for(int i=0;i<m;i++){
int op;
cin >> op;
if(op==1){
int l,r,k;
cin >> l >> r >> k;
while(1){
int pos=*(st.lower_bound(l)); //st中第一个大于等于l的坐标
if(pos>r) break; //需要修改的坐标不在[l,r]中,break
for(int j=0;j<min(k,(int)20);j++){
sum-=a[pos]; //减去原来的值
a[pos]=f(a[pos]); //进行修改
sum+=a[pos]; //加上修改的值
}
if(a[pos]==f(a[pos])) st.erase(pos); //该值恒定不变了删除即可
l=pos+1; //找满足条件的下一个坐标
}
}
else{
cout << sum << endl;
}
}
}
signed main(){
int t=1;
// cin >> t;
while(t--){
solve();
}
return 0;
}
M-本题主要考察了找规律
M-本题主要考察了找规律_2023牛客寒假算法基础集训营1 (nowcoder.com)
思路:简单dp,但我太笨没看出来....
f[i][j] 表示给i个人分j个仙贝得到的最大好感度。
i 个人 分 j 个仙贝 得到的好感度可由 i-1 个人转移而来,则枚举第i 个人分到仙贝数k个。
k 的范围是 [0,j] ,且第i个人的好感贡献就是 k/(m-(j-k))。最后输出f[n][m]即可。
#include<bits/stdc++.h>
#define int long long
using namespace std;
double n,m;
double f[505][505];
void solve(){
cin >> n >> m ;
for(int i=1;i<=n;i++){
for(int j=0;j<=m;j++){
for(int k=0;k<=j;k++){ //枚举第i个人分到的仙贝数k
//第i个人对好感度的贡献就是 k/(总数-分给前(i-1)个人的仙贝数)
f[i][j]=max(f[i][j],f[i-1][j-k]+(double)(k)/(double)(m-(j-k)));
}
}
}
printf("%.9lf",f[(int)n][(int)m]);
}
signed main(){
int t=1;
// cin >> t;
while(t--){
solve();
}
return 0;
}
E-鸡算几何
E-鸡算几何_2023牛客寒假算法基础集训营1 (nowcoder.com)
思路:
叉积,不是很会,放一份代码
#include<bits/stdc++.h>
#define int long long
#define pdd pair<double,double>
#define x first
#define y second
using namespace std;
pdd p[6];
double len(pdd a,pdd b){
return a.x*b.x+a.y*b.y;
}
double cross(pdd a,pdd b){
return a.x*b.y-a.y*b.x;
}
pdd sub(pdd a,pdd b){
return {a.x-b.x,a.y-b.y};
}
void solve(){
for(int i=0;i<6;i++){
cin >> p[i].x >> p[i].y;
}
if(cross(sub(p[0],p[1]),sub(p[2],p[1]))<0.0) swap(p[0],p[2]);
if(cross(sub(p[3],p[4]),sub(p[5],p[4]))<0.0) swap(p[3],p[5]);
double len0=sqrt(len(sub(p[0],p[1]),sub(p[0],p[1])));
double len1=sqrt(len(sub(p[3],p[4]),sub(p[3],p[4])));
if(fabs(len0-len1)>1E-9) cout << "YES" << endl;
else cout << "NO" << endl;
}
signed main(){
int t=1;
cin >> t;
while(t--){
solve();
}
return 0;
}