niuniu小白63 atc259补题

目录

小白53

Mising:

贪心+dp:

Calling:

AtCoder Beginner Contest 259 - AtCoder

A.签到

B.三角函数

C.s变成t串构造

D.并查集


小白53

签到:多个元素与同一个元素比较,输出此类用数组直接for快一些

数学:化简公式后注意取模顺序不能爆ll

Mising:

题意:实现找多个同长度字符串中最大价值,排序

自己想直接stl过,结果没考虑出现同种字符串及其提醒没有满足得话全部排序后输出

正解:结构体排序

struct node
{
    string ss;double ans;
}q[150];
 
bool cmp(node a,node b)
{
    if(a.ans==b.ans)return a.ss<b.ss;
    return a.ans>b.ans;
}
void solved()
{
    string s;cin>>s;
    int len1=s.size();
    int n;cin>>n;
    double mx=0;
 
    for(int i=1;i<=n;i++)
    {
        cin>>q[i].ss;
        if(q[i].ss.size()!=len1)q[i].ans=0;
        else{
            int cnt=0;
            for(int j=0;j<len1;j++)
                if(q[i].ss[j]==s[j])cnt++;
            q[i].ans=cnt*1.0/len1;
        }
    }
    sort(q+1,q+n+1,cmp);
    mx=q[1].ans;
    for(int i=1;i<=n;i++)
        if(mx==q[i].ans)cout<<q[i].ss<<'\n';
 
}

贪心+dp:

题意:重新构造数组,取值为1到原数组的价值,使差值和最大

自己想贪心找最大两边填1去构造,wa了3发

最后都说是dp的情况下自己独立写出来了!!!

思路:已经知道选1或者q[i]最优,设状态f[i][0],f[i][1]表示前i项第i项选q[i]和1时的最大值

状态转移:看最后一步,那么一定从前一项的情况来,前一项只能是f[i-1][0],f[i-1][1]转移想对了,只要顺序遍历到目标,无论我转移受否重复我取max都会更新掉(参考公共子序列),再看一下此时是谁和谁做差就行

计数的话就必须状态转移清楚

const int N = 1e5 + 10;
ll q[N],f[N][2];
 
void solved()
{
    ll n;cin>>n;
    for(int i=1;i<=n;i++)cin>>q[i];
    f[1][0]=0;
    f[1][1]=0;
     
    for(int i=2;i<=n+1;i++)
    {
        f[i][0]+=max(f[i-1][1]+abs(q[i]-1),f[i-1][0]+abs(q[i]-q[i-1]));
        f[i][1]+=max(f[i-1][1]+abs(1-1),f[i-1][0]+abs(1-q[i-1]));
    }
     
    print(max(f[n][0],f[n][1]),'\n');
}

Calling:

贪心

题意:给你s个6*6的块,问给出边长为1,2,3,4,5,6的个数时,能否够装下

正解:贪心去装,6,5,4他们一定占满,先装,再3

详细看代码

#include<bits/stdc++.h>
using namespace std;
 
int main() {
  int t; cin >> t;
  while (t--) {
    int s; cin >> s;
    int a, b, c, d, e, f;cin >> a >> b >> c >> d >> e >> f;

    //d,e,f装满,c最多能装4个,装不下向上取整
    int cnt;cnt = d + e + f + ceil(c*1.0 / 4);
    //在考虑装2*2

    int cntb= d * 5;//装满的4*4中刚好还能装5个
    if (c % 4 != 0) {
    //模拟3*3装了%4个后还能装2*2的个数
      if (c % 4 == 3) cntb += 1;
      if (c % 4 == 2) cntb += 3;
      if (c % 4 == 1) cntb += 5;
    }
    //b还有剩下,自己单独装2*2->6*6
    if (b > cntb) {
      cnt += ceil((b - cntb)*1.0 / 9);
    }

    int ans;
    ans = 6 * 6 * f + 5 * 5 * e + 4 * 4 * d + 3 * 3 * c + 2 * 2 * b;
    //最后看a能否填满之前的
    int cnta=6 * 6 * cnt - ans;

    //还有剩余单独装
    if (a > cnta) { 
      cnt += ceil((a - cnta)*1.0 / 36);
    }
    //贪心完后比较总块数够不够
    cout << (cnt <= s ? "Yes" : "No") << endl;
  }
}

AtCoder Beginner Contest 259 - AtCoder

A.签到

特判T时刻生日和目标时刻生日的大小,如果M为1到X-1那就需要找M时候年轻是多少岁

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define pb push_back
#define lowbit(x) x&-x
const int N = 1e5+10,mod=1e9+7;
void fast(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);}
#define endl '\n'
int n,m,x,t,d;
int a[N];
void solve(){
	cin>>n>>m>>x>>t>>d;
	if(m>=x){
		cout<<t<<endl;
	}else{
		cout<<t-(x-m)*d<<endl;
	}
}
int main() {
	fast();
	int _=1;
	//cin>>t;
	while(_--){
		solve();
	}
	return 0;
}

B.三角函数

求a,b逆时针转d度数后的坐标

特判0,0

ab转换成sinα,cosα,展开弧度加和ccss,sccs

弧度制rd=d*pi/180,pi=acos(-1)

#include <bits/stdc++.h>

using namespace std;

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);

  int a, b, d;cin >> a >> b >> d;
  double len = sqrt(a * a + b * b);
  if (!a&&!b) {
    cout << "0 0\n";
    return 0;
  }
  double cosa = a / len,sina = b / len,pi = acos(-1),rd = d * pi / 180;
  printf("%.20lf %.20lf",
len * (cosa * cos(rd) - sina * sin(rd)),
 len * (sina * cos(rd) + cosa * sin(rd)));

  return 0;
}

C.s变成t串构造

双指针跑一遍,returnNo的解,指针顺序遍历到n+1则有解

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

inline int rd() {
    int x = 0;
    bool f = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) f |= (c == '-');
    for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
    return f ? -x : x;
}

#define N 3007

ll x[N], y[N], r[N];

int f[N];

int find(int x) {
    return x == f[x] ? x : (f[x] = find(f[x]));
}

inline ll sqr(ll x) {return x * x;}

int main() {
    int n = rd();
    for (int i = 1; i <= n; ++i) f[i] = i;
    int sx = rd(), sy = rd();
    int tx = rd(), ty = rd();
    for (int i = 1; i <= n; ++i) {
        x[i] = rd(); y[i] = rd(); r[i] = rd();
    }
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j) {
            if (sqr(x[i] - x[j]) + sqr(y[i] - y[j]) > sqr(r[i] + r[j])) continue;
            if (sqr(x[i] - x[j]) + sqr(y[i] - y[j]) < sqr(r[i] - r[j])) continue;
            int u = find(i), v = find(j);
            f[u] = v;
        }
    int px, py;
    for (int i = 1; i <= n; ++i) {
        if (sqr(sx - x[i]) + sqr(sy - y[i]) == sqr(r[i])) px = i;
        if (sqr(tx - x[i]) + sqr(ty - y[i]) == sqr(r[i])) py = i;
    }
    puts(find(px) == find(py) ? "Yes" : "No");
    return 0;
}

D.并查集

题意:给定起点终点,圆

on方+并查集

只要圆相即不包含和相离则并查集连下标

找到起点和终点所在的圆

看是否联通

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

inline int rd() {
    int x = 0;
    bool f = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) f |= (c == '-');
    for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
    return f ? -x : x;
}

#define N 3007

ll x[N], y[N], r[N];

int f[N];

int find(int x) {
    return x == f[x] ? x : (f[x] = find(f[x]));
}

inline ll sqr(ll x) {return x * x;}

int main() {
    int n = rd();
    for (int i = 1; i <= n; ++i) f[i] = i;
    int sx = rd(), sy = rd();
    int tx = rd(), ty = rd();
    for (int i = 1; i <= n; ++i) {
        x[i] = rd(); y[i] = rd(); r[i] = rd();
    }
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j) {
            if (sqr(x[i] - x[j]) + sqr(y[i] - y[j]) > sqr(r[i] + r[j])) continue;
            if (sqr(x[i] - x[j]) + sqr(y[i] - y[j]) < sqr(r[i] - r[j])) continue;
            int u = find(i), v = find(j);
            f[u] = v;
        }
    int px, py;
    for (int i = 1; i <= n; ++i) {
        if (sqr(sx - x[i]) + sqr(sy - y[i]) == sqr(r[i])) px = i;
        if (sqr(tx - x[i]) + sqr(ty - y[i]) == sqr(r[i])) py = i;
    }
    puts(find(px) == find(py) ? "Yes" : "No");
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值