学习日记2(2023.2.13)

1.ABC123b
题意:一个国家,有多个城市,一个城市有多个参观点。输入给出参观点的城市、名称以及好评度,请输出对应参观点的排名(从1开始)。排名规则:按字典序参观城市,按好评度顺序参观参观点。

解法:字符串套字符串,一层一层剥开排序

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ft first
#define sd second
#define P pair<int,int>
#define TT int tt;for(cin>>tt;tt--;)
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
const int N=2e5+5;
const int NN=1e6+6;
const int mod=1e9+7;
int b[N],a[N];
vector<int>v;
unordered_map<int,int>mp;
string s;
int n,m;
int ans=0;
//x,y,z; sum,res,cur,tmp; l,r,ll,rr; p,pp;
//暴力枚举,前缀和,二分,dfs,双指针,差分,并查集,逆元

void solve()
{
	pair<pair<string,int>,int> p[110];
	cin>>n;
	for(int i=0;i<n;i++)
	{
		int t;
		string tmp;
		cin>>tmp>>t;
		p[i]=make_pair(make_pair(tmp,-t),i);
	}
	sort(p,p+n);
	for(int i=0;i<n;i++)
		cout<<p[i].sd+1<<'\n';
}
signed main()
{
	//TT
	solve();
	return 0;
}

/*
khabarovsk 20  4 1
moscow 10      6 2
kazan 50       1 3
kazan 35       2 4
moscow 60      5 5
khabarovsk 40  3 6
*/

2.ABC99c
题意:已知n,求满足该式子pow(6,x)+pow(9,y)+z==n的最小的(x+y+z)的和值。
解法关键词:递归
eg:这样的题我做的不多,也不熟,是弱项。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ft first
#define sd second
#define P pair<int,int>
#define TT int tt;for(cin>>tt;tt--;)
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
const int N=2e5+5;
const int NN=1e6+6;
const int mod=1e9+7;
int b[N],a[N];
vector<int>v;
unordered_map<int,int>mp;
string s;
int n,m;
int ans=0;
//x,y,z; sum,res,cur,tmp; l,r,ll,rr; p,pp;
//暴力枚举,前缀和,二分,dfs,双指针,差分,并查集,逆元

int f(int x,int y)
{
	return x?f(x/y,y)+x%y:0;
}
void solve()
{
	cin>>n;
	ans=LLONG_MAX;
	for(int i=0;i<=n;i++)
	{
		ans=min(ans,f(i,6)+f(n-i,9));
	}
	cout<<ans;
}
signed main()
{
	//TT
	solve();
	return 0;
}

3.ARC98b
题意:给定一个数组b,选择一对l,r(l<=r),使得b[l]^...b[r]=b[l]+...b[r]。

解法:双指针,前一个数到后一个数(最远)的和。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ft first
#define sd second
#define P pair<int,int>
#define TT int tt;for(cin>>tt;tt--;)
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
const int N=2e5+5;
const int NN=1e6+6;
const int mod=1e9+7;
int b[N],a[N];
vector<int>v;
unordered_map<char,bool>mp;
string s;
int n,m;
int ans=0;
//x,y,z; sum,res,cur,tmp; l,r,ll,rr; p,pp;
//暴力枚举,前缀和,二分,dfs,双指针,差分,并查集,逆元

set<int>st;
void solve()
{
	cin>>n;
	for(int i=1;i<=n;i++)cin>>b[i];
	int j=1,s=0;
	for(int i=1;i<=n;i++)
	{
		while((s^b[i])!=s+b[i])s^=b[j],j++;
		s^=b[i];
		ans+=i-j+1;
	}
	cout<<ans;
}
signed main()
{
	//TT
	solve();
	return 0;
}

4.ABC97b
题意:给定一个n,求最接近n的pow(x,y),并输出。
解法:形如素数筛的原理。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ft first
#define sd second
#define P pair<int,int>
#define TT int tt;for(cin>>tt;tt--;)
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
const int N=2e5+5;
const int NN=1e6+6;
const int mod=1e9+7;
int b[N],a[N];
vector<int>v;
unordered_map<int,int>mp;
string s;
int n,m;
int ans=0;
//x,y,z; sum,res,cur,tmp; l,r,ll,rr; p,pp;
//暴力枚举,前缀和,二分,dfs,双指针,差分,并查集,逆元


void solve()
{
	cin>>n;
	int r=1;
	for(int i=2;i<=n;i++)
	{
		for(int j=i*i;j<=n;j*=i)
			r=max(r,j);
	}
	cout<<r;
}
signed main()
{
	//TT
	solve();
	return 0;
}

5.ARC97b

题意:给定一个数序列b,再给定两两位置可进行交换的l和r,对可交换位置的树进行任意次操作,求b[i]==i的最大数量。
解法:并查集
eg:小心超时,find函数用递归法比较好。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ft first
#define sd second
#define P pair<int,int>
#define TT int tt;for(cin>>tt;tt--;)
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
const int N=2e5+5;
const int NN=1e6+6;
const int mod=1e9+7;
int b[N],fa[N];
//vector<int>v;
unordered_map<int,int>mp;
string s;
int n,m;
int ans=0;
//x,y,z; sum,res,cur,tmp; l,r,ll,rr; p,pp;
//暴力枚举,前缀和,二分,dfs,双指针,差分,并查集,逆元


int find(int x)
{
	return x==fa[x]?x:fa[x]=find(fa[x]);
}
void merge(int x,int y)
{
	int fx=find(x);
	int fy=find(y);
	//if(fx!=fy)
	fa[fx]=fy;
}
void solve()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>b[i],fa[i]=i;
	for(int i=0;i<m;i++)
	{
		int x,y;
		cin>>x>>y;
		merge(x,y);
	}
	for(int i=1;i<=n;i++)
	{
		if(find(i)==find(b[i]))ans++;
	}
	cout<<ans;
}
signed main()
{
	//TT
	solve();
	return 0;
}

6.ABC96d
题意:构造一个长度为n的数列,要求数组元素全为素数,且任意5个数的和不为质数。
解法:使任意5个数的和为5的倍数,则数组元素全为个位为1的质数。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ft first
#define sd second
#define P pair<int,int>
#define TT int tt;for(cin>>tt;tt--;)
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
const int N=2e5+5;
const int NN=1e6+6;
const int mod=1e9+7;
int b[N],a[N];
//vector<int>v;
//unordered_map<int,int>mp;
string s;
int n,m;
int ans=0;
//x,y,z; sum,res,cur,tmp; l,r,ll,rr; p,pp;
//暴力枚举,前缀和,二分,dfs,双指针,差分,并查集,逆元
char mp[55][55];
int d[][2]={{0,1},{0,-1},{-1,0},{1,0}};
const int M=55556;
bool prime[M];

void solve()
{
	for(int i=2;i<M;i++)
	{
		if(prime[i]==0)
			for(int j=i+i;j<M;j+=i)
				prime[j]=1;
	}
	cin>>n;
	int x=11;
	while(n--)
	{
		while(prime[x])x+=10;
		cout<<x<<" ";
		x+=10;
	}
}
signed main()
{
	//TT
	solve();
	return 0;
}

7.ARC96b
题意:有一张圆桌,给定一个n,在0到n之间有美食若干,顺时针顺序给定美食饱腹度。每移动1单位,会消耗1能量。你从0开始,任意围着圆周行走吃美食,并可以在任意位置离开圆桌。求最终的满意度最大是多少。(美食饱腹度总量-消耗总量)另外,你不会饿死,也不会撑死。

解法:有点前缀和的感觉,这个题还得再写写,现在还有些没懂思路。
eg:欢迎指正!

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define INF 1e18
#define ft first
#define sd second
#define P pair<int,int>
#define TT int tt;for(cin>>tt;tt--;)
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
const int N=2e5+5;
const int NN=1e6+6;
const int mod=1e9+7;
int b[N],a[N];
//vector<int>v;
unordered_map<int,int>mp;
string s;
int n,m;
//int ans=0;
//x,y,z; sum,res,cur,tmp; l,r,ll,rr; p,pp;
//暴力枚举,前缀和,二分,dfs,双指针,差分,并查集,逆元
int k,x[N],v[N],c[N],d[N];
int vtl=0,vtr=0,ans=-INF;

void solve()
{
	cin>>n>>k;
	for(int i=0;i<n;i++)cin>>x[i]>>v[i];
	for(int i=0;i<n;i++)
	{
		vtl+=v[i];
		vtr+=v[n-i-1];//-1
		a[i+1]=max(a[i],vtl-x[i]);
		b[i+1]=max(b[i],vtl-x[i]*2);
		c[n-i-1]=max(c[n-i],vtr-(k-x[n-i-1]));
		d[n-i-1]=max(d[n-i],vtr-(k-x[n-i-1])*2);
	}
	for(int i=0;i<=n;i++)ans=max(ans,max(a[i]+d[i],b[i]+c[i]));//==n
	cout<<ans;
}
signed main()
{
	//TT
	solve();
	return 0;
}
//1e5*1000

8.ARC95b
题意:给定n个数,找出两个数,使得组合数C(x,y)最大,并输出。
解法:很好的代码写法,往中靠。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ft first
#define sd second
#define P pair<int,int>
#define TT int tt;for(cin>>tt;tt--;)
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
const int N=2e5+5;
const int NN=1e6+6;
const int mod=1e9+7;
int b[N],a[N];
vector<int>v;
unordered_map<int,bool>mp;
string s;
int n,m;
int ans=0;
//x,y,z; sum,res,cur,tmp; l,r,ll,rr; p,pp;
//暴力枚举,前缀和,二分,dfs,双指针,差分,并查集,逆元

void solve()//2 3 4 4
{
	cin>>n;
	for(int i=0;i<n;i++)cin>>b[i],mp[b[i]]=1;
	sort(b,b+n);
	for(int i=0;i<n-1;i++)
	{
		if(min(b[i],b[n-1]-b[i])>m)m=b[i];//往中间找
	}
	cout<<b[n-1]<<" "<<m;
}
signed main()
{
	//TT
	solve();
	return 0;
}

posted @ 2023-02-13 15:45  gaogesing夏花夕  阅读(51)  评论(0)    收藏  举报
/////////////////////////////////////////////////////////////////////////////////////////////////////