寒假训练第二周
第一天
蓝桥杯模拟赛2
F.平面切分
大意:
N条直线,给定解析式,输出被分成的平面数
思路:
若所添加的直线与之前直线平行,平面数+1
若与已有直线每产生一个不同位置交点是,平面数额外+1
最后再加上原来的一个平面
代码:
#include <bits/stdc++.h>using namespace std;
#define ll long longconst ll N=1e5+10;
#define endl '\n'long double s[1010][2];
ll ans;
bool st[1010];
pair<long double,long double> p;
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>s[i][0]>>s[i][1];
set<pair<long double,long double>> points;
for(int j=0;j<i;j++){
if(st[j])continue;
if(s[i][0]==s[j][0]){
if(s[i][1]==s[j][1]){
st[i]= true;
break;
}else continue;
}
p.first=(s[j][1]-s[i][1])/(s[i][0]-s[j][0]);
p.second=s[i][0]*p.first+s[i][1];
points.insert(p);
}
if(!st[i])ans+=points.size()+1;
}
cout<<ans+1;
return 0;
}
第二天
牛客竞赛
1010 华华听月月唱歌
大意:
歌曲分成数个片段(有重复)
问最少几个片段可以还原整首歌曲
思路:
预先模拟
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=1e5+10;
#define endl '\n'
int main()
{
int n,m,mi=0,ma=0,res=0;
pair<int,int> pie[100007];
cin>>n>>m;
for(int i=0;i<m;i++){
cin>>pie[i].first>>pie[i].second;
}
sort(pie,pie+m);
for(int i=0;i<m;i++){
if(pie[i].first>ma+1){
cout<<-1;
break;
}
if(pie[i].first>mi+1){
res++;
mi=ma;
}
if(pie[i].first<=mi+1){
ma=max(ma,pie[i].second);
if(ma>=n){
cout<<res+1;
break;
}
}
}
return 0;
}
第三天
中文个人赛
A.异或橙子
大意:
求区间中所有子区间的异或和的异或和
有修改和区间询问
思路:
一个数异或本身为0
找规律
当区间两端的数奇偶性不同时答案为0
相同时区间内奇偶性与端点一致时需进行异或
奇偶两个树状数组
lowbit(x) x&(-x)
修改操作:a[i]^x
代码:
#include <bits/stdc++.h>using namespace std;
#define ll long longconst ll N=2e5+10;
#define endl '\n'#define lowbit(x) x&(-x)int m,n;
int a[N];
struct name{
int c[4*N];
void add(int x,int y){
for(int i=x;i<=n;i+=lowbit(i)){
c[i]^=y;
}
}
int sum(int x){
int res=0;
for(int i=x;i;i-= lowbit(i))res^=c[i];
return res;
}
}b[2];
int main(){
ios::sync_with_stdio(false);
cin.tie(),cout.tie();
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
b[i&1].add(i,a[i]);
}
while(m--){
int op,i,j;
cin>>op>>i>>j;
if(op==1){
b[i&1].add(i,a[i]^j);
a[i]=j;
}else{
if((i&1)!=(j&1)) cout<<0<<endl;
else{
int op=b[i&1].sum(j)^b[i&1].sum(i-1);
cout<<op<<endl;
}
}
}
return 0;
}
E.直播获奖
大意:
每计算出一名选手的分数,根据获奖比更新获奖选手数量以及分数线,输出每一次的分数线
思路:
动态维护获奖分数的最低分
对顶堆
代码:
#include <bits/stdc++.h>using namespace std;
#define endl '\n'#define ll long longconst ll N=1e5+10;
priority_queue<int> ma;
priority_queue<int, vector<int>, greater<int> > mi;
int n, w, now, num;
void qwq(){
if (mi.size()<now)
{
mi.push(ma.top());
ma.pop();
}
if (mi.size() > now)
{
ma.push(mi.top());
mi.pop();
}
}
void push(int num){
if (num >= ma.top()) mi.push(num);
else ma.push(num);
qwq();
}
int main(){
scanf("%d%d", &n, &w);
ma.push(0);
for (int p = 1; p <= n; p++)
{
now=max(1,p*w/100);
scanf("%d", &num);
push(num);
printf("%d ", mi.top());
}
return 0;
}
第四天
cf#843 Div.2
A.A1. Gardener and the Capybaras (easy version)
大意:
把给定字符串分成三部分
让第二部分大于第一部分和第三部分或小与第一部分和第三部分
思路:
暴力
代码:
#include <bits/stdc++.h>using namespace std;void solve(){ string ch; cin >> ch; int n = ch.size(); ch = ' ' + ch; for(int i = 1; i < n; i ++) for(int j = i + 1; j < n; j ++ ) { string a = ch.substr(1, i), b = ch.substr(i + 1, j - i), c = ch.substr(j +
1, n - j); if((a <= b && c <= b) || (a >= b && c >= b)) { cout << a << ' ' << b << ' ' << c << endl; return; } }}int main(){ int T = 1; cin >> T; while( T -- ) solve(); return 0;}
第五天
cf排位赛
B.Hotpot
大意:
n个人,k种食材,m次操作
给定每人爱吃的食材,
轮到一个人,若此时没有他爱吃的则放入,否则吃掉,快乐+1
问每个人最后的快乐值
思路:
一轮下来,爱吃同一种食材的人分奇偶
故两轮一个循环
不足一轮的单独再跑
代码:
#include<iostream>
#include<cstring>
using namespace std;
const int N=1e5+10;
struct f{
int x;
int happy;
}a[N];
int v[N];
long long n,k,m;
int main()
{
int t;
cin>>t;
while(t--)
{
memset(v,0,sizeof(v));
cin>>n>>k>>m;
for(int i=0;i<n;i++){
cin>>a[i].x;
a[i].happy=0;
}
if(m>=2*n)
{
for(int i=0;i<2*n;i++)
{
int j=i%n;
if(v[a[j].x]==0){
v[a[j].x]++;
}else{
v[a[j].x]--;
a[j].happy++;
}
}
for(int i=0;i<n;i++)
a[i].happy*=(m/(2*n));
}
for(int i=0;i<m%(2*n);i++)
{
int j=i%n;
if(v[a[j].x]==0)v[a[j].x]++;
else
{
v[a[j].x]--;
a[j].happy++;
}
}
for(int i=0;i<n;i++)
{
if(i)cout<<" ";
cout<<a[i].happy;
}
cout<<endl;
}
return 0;
}
第六天
每日一题
A.糖果
大意:
M种口味的糖果,K颗一包(注明口味),给定N包,问最少需几包能品尝到所有口味
思路:
二进制01状态表示一包中是否包含该口味
背包计算最少需几包
代码:
#include<bits/stdc++.h>using namespace std;
#define MAXN 105int N,M,K,tmp;
int f[1<<20],a[MAXN];
int main(){
cin>>N>>M>>K;
for(int i=0;i<N;i++){
for(int j=0;j<K;j++){
cin>>tmp;
a[i]|=1<<tmp-1;
}
}
memset(f,127,sizeof f);
f[0]=0;
for(int i=0;i<N;i++){
for(int S=0;S<1<<M;S++){
if(f[S]>MAXN)continue;
f[S|a[i]]=min(f[S|a[i]],f[S]+1);
}
}
cout<<(f[(1<<M)-1]<MAXN?f[(1<<M)-1]:-1)<<endl;
return 0;
}
C.垒骰子
大意:
垒n个骰子,输入排斥对,排斥对不能紧挨,问有多少种垒的方式
思路:
dp
优化成矩阵乘法
矩阵快速幂
代码:
#include<bits/stdc++.h>using namespace std;
typedef long long ll;
const ll MOD = 1e9+7;
ll n, m;
int a, b;
int opp[7] = {0, 4, 5, 6, 1, 2, 3};
struct Matrix {
ll m[10][10];
int row, col;
Matrix (int r, int c, int fill) {
row = r, col = c;
for (int i = 1;i <= r;i ++)
for (int j = 1;j <= c;j ++)
m[i][j] = fill;
}
Matrix (int r) {
row = r, col = r;
memset (m, 0, sizeof m);
for (int i = 1;i <= r;i ++)
m[i][i] = 1;
}
ll Sum () {
ll res = 0;
for (int i = 1;i <= row;i ++)
for (int j = 1;j <= col;j ++)
res = (res + m[i][j]) % MOD;
return res;
}
};
Matrix Matrix_Mul (Matrix a, Matrix b) {
Matrix c = Matrix(a.row, b.col, 0);
for (int i = 1;i <= a.row;i ++)
for (int j = 1;j <= b.col;j ++)
for (int k = 1;k <= a.col;k ++)
c.m[i][j] = (c.m[i][j] + a.m[i][k] * b.m[k][j] % MOD) % MOD;
return c;
}
Matrix KSM (Matrix matrix, ll p) {
Matrix res = Matrix (6);
while (p) {
if (p & 1) res = Matrix_Mul (res, matrix);
matrix = Matrix_Mul (matrix, matrix);
p >>= 1;
}
return res;
}
int main(){
cin >> n >> m;
Matrix T = Matrix (6, 6, 4);
Matrix A = Matrix (6, 1, 4);
while (m -- ) {
cin >> a >> b;
T.m[opp[a]][b] = T.m[opp[b]][a] = 0;
}
Matrix T_pow = KSM (T, n-1);
cout << Matrix_Mul (T_pow, A).Sum() << endl;
return 0;
}
标签:std,ch,训练,int,ll,long,第二周,寒假,define
From: https://www.cnblogs.com/wwww-/p/17053870.html