目录
AtCoder Beginner Contest 259 - AtCoder
小白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;
}