A CCPC
手速题
x = input()
y = "CCPC"
if y in x :
print("Hello CCPC!")
else :
print("This is not my CCPC")
B 道路
D国有n个城市,由于城市之间并没有公路,交通十分不方便。
D国国王希望修建n−1条公路,使得对于任意两个城市,都可以通过公路互相到达。
建造公路的任务由各个城市负责,具体来说,每个城市都会给出建造公路的费用,第i个城市修建公路的费用为di。而对于一条连接x,y两座城市的公路,它的建造任务会由x,y两座城市中修建费用较小的城市来负责修建。整个建造方案的费用为每条公路的建造费用之和。
工程师给出了一个建造方案,但国王认为方案成本略高,他希望工程师修改方案。但出于某种原因,工程师只能在方案中更改不超过k条公路,并且要保证更改后任意两座城市仍然可以通过公路相互到达。你能帮助他算一算在更改方案后最小的建造费用吗?
输入格式:
第一行输入两个正整数n,k(1≤n≤105,0≤k<n)。
接下来一行输入n个正整数di(1≤di≤n)表示第i个城市建造公路的费用。
接下来n−1输入初始的建造方案,每个行包含两个正整数x,y(1≤x,y≤n),代表初始建造方案。保证输入是一个合法的方案。
输出格式:
输出一行一个正整数表示最小的成本。
思路:
将大的边换成最小的边即可,因为输入的方案数保证连通的,删除花费最大的边后与花费最小的顶点连接即可
#include <iostream>
#include <queue>
#include <vector>
#define MAX_V 100002
using namespace std;
int n,k,price[MAX_V];
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
cin>>n>>k;
int minn=1<<30;
for(int i=1;i<=n;i++)
{
cin>>price[i];
minn=min(minn,price[i]);
}
priority_queue<int>que;// 大顶堆
long long ans=0 ;
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
ans+=min(price[u],price[v]);
que.push(min(price[u],price[v]));
}
while(k--){
//将最大的边取出
ans-=que.top();que.pop();
ans+=minn;
}
cout<<ans;
return 0;
}
D 函数
Ax^2+Bx+C;
给系数和区间端点求区间最小最大值
思路:
1、 A=0 and B=0 f(x)= C minn=maxn =C
2、 A=0 and B!=0 y= Bx+C minn = min(f(L),f(R)) maxn=max(f(L),f(R))
3、 A!=0 and B!=0
mid = -(b/2a)
indx_up = ecil(mid)//向上取整
indx_d = floor(mid)//向下取整
判断 indx_up 、indx_d 是否在区间[L,R]中
f(indx_up)、f(indx_d)、f(L)、f(R)
最小、最大即可
#include <iostream>
#include <cmath>
#define ll long long
using namespace std;
void solve(){
ll A,B,C,L,R;
cin>>A>>B>>C>>L>>R;
if(A==0 && B==0){
//常数型函数 y=c
cout<<C<<" "<<C<<"\n";
}else if(A==0 ){
//A为0 B不为 0 此时为一元一次函数
ll aL = A*L*L + B*L +C;
ll aR = A*R*R + B*R +C;
ll minn = 1LL*min(aL,aR);
ll maxn = 1LL*max(aL,aR);
cout<<minn<<" "<<maxn<<"\n";
}else{
//A于B均不为0 即一元二次函数
double mid = - (B / (2.0*A)) ;//对称轴 //向上取整和向下取整
ll midu= ceil(mid) , midd = floor(mid);
//极值点只有三位置可能 俩个端点、对称轴位置
ll aL = A*L*L + B*L +C;
ll aR = A*R*R + B*R +C;
ll amu = A*midu*midu + B*midu +C;
ll amd = A*midd*midd + B*midd +C;
ll minn = 1LL*min(aL,aR);
ll maxn = 1LL*max(aL,aR);
if( midu >=L && midu<=R){
minn = min (minn,amu);
maxn = max (maxn,amu);
}
if(midd >=L && midd <=R){
minn = min(minn,amd);
maxn = max(maxn,amd);
}
cout<< minn<<" "<<maxn<<"\n";
}
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
E二进制
多推几个样例
发现答案要么是n要么是n+1要么是n+2(大胆的猜结论 )
eg:
11(2)=3
101(2)=5
110(2)=6
1001(2)=9
1010(2)=10
1100(2)=12
1111(2)=15
…………
自此假设n取 [1, 15]
n = 1
1 X
1+1 √
n= 2
2√
n=3
3 X
4 X
5 √
n=4
4 X
5 √
…………
#include <iostream>
#include <cmath>
#define ll long long
using namespace std;
bool solve1(int x){
int cnt=0;
while(x/2!=0){
cnt+=x%2;
x/=2;
}
cnt+=x%2;
return (cnt%2==0);
}
void solve(){
int n;
cin>>n;
if(solve1(n)){
cout<<n;
}else if(solve1(n+1)){
cout<<n+1;
}else if(solve1(n+2)){
cout<<n+2;
}
cout<<"\n";
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
H 修复括号序列
模拟
( 贡献度 +1
)贡献度 -1
需要注意可以修改至多1次
当)优先多于(数量时候必须修改一次 如果修改后仍然出现该情况则 输出NO
如果最后value= 2 (未修改过)那么输出YES
剩下即value = 0 YES
value !=0 NO
#include <iostream>
#include <cmath>
#include <cstring>
#define ll long long
using namespace std;
void solve(){
int n;string temp;
cin>>n>>temp;
int cnt=0,x=0;
for(int i=0;i<n;i++){
if(temp[i] == '(' )cnt++;
else if(temp[i] == ')')cnt--;
if(cnt<0 && x==0){
x++;
cnt+=2;
}else if(cnt<0){
cout<<"No";
return;
}
}
if(x==0 && (cnt==0 || cnt==2)){
cout<<"Yes";
}else if(cnt==0){
cout<<"Yes";
}else{
cout<<"No";
}
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int t=1;
//cin>>t;
while(t--){
solve();
}
return 0;
}
I石子游戏
多推几个样例 找规律
B B B B B
1 2 3 4 5 6 7 8 9 10 11
A A A A A A会发现 以n方开始长度为n区间内Alice Win 否则 Bob Win n∈N+
#include <iostream>
#include <cmath>
#include <cstring>
#define ll long long
using namespace std;
void solve(){
ll n;
cin>>n;
ll a=sqrt(n);
ll b=a * a +a;
if( n>=a && n<b){
cout<<"Alice\n";
}else{
cout<<"Bob\n";
}
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int t=1;
cin>>t;
while(t--){
solve();
}
return 0;
}
J 密码
解释:
条件:
p,q是质数
A*p+B*q=p*q的倍数 <<==>> Ap+Bq=kpq <<==>> Ap = kpq - Bq <<==>> Ap = (kp-B)q根据这个式子Ap = (kp-B)q
可以得到俩个信息
有可能 p==q
如果p == q
则A = kp -B
A+B = kp
p就是(A+B)的质因子
p的可能个数为(A+B)的质因子个数如果 p!=q
那么原式改写成
A/q+B/p=k k∈N+
那么q一定是A的质因子,p一定是B的质因子
组合情况就是A的质因子个数 *B的质因子个数
但是A的质因子可能与B的质因子个数相同 使得p==q与第一种情况有可能重复了需要减去
假设 Sa是含A的质因子的集合,Sb是含B质因子的集合result = fac(A)*fac(B);
假设 存储A质因子元素的集合为Sa、存储B质因子元素的集合为Sb
存储交集元素集合为vis
如果 vis集合中元素未出现(A+B)的质因子元素,且元素个数为x则result需要加上x综上所述
result = fac(A)*fac(B) + x;*/
#include <bits/stdc++.h>
#define INT64_MAX 0x7fffffffffffffff
const int N = 1e6 +7;
#define ll long long
using namespace std;
vector<int> prime;//存储质数
bitset<N>isprime;// 判断i是不是质数
void euler(int n){
isprime.set();//全部置1
isprime[1]=0;
for(int i=2;i<=n;i++){
if(isprime[i]){
prime.push_back(i);
}
for(int j=0;j<prime.size() && i*prime[j]<=n;j++){
isprime[i*prime[j]] = 0;
if( i% prime[j] == 0){
break;
}
}
}
}
set<ll> fac(ll x){
set<ll>s;
for(int i=0;i<prime.size();i++){
if(1LL* prime[i]*prime[i]>x){
break;
}
if(x % prime[i] == 0){
s.insert(prime[i]);
while(x % prime[i] == 0){
x/=prime[i];
}
}
}
if(x>1){
s.insert(x);
}
return s;
}
void solve(){
ll a,b;
cin>>a>>b;
set<ll> faca = fac(a);
set<ll> facb = fac(b);
ll res = faca.size() * facb.size();
set<ll>vis;
for(set<ll>::iterator it=faca.begin();it!=faca.end();it++){
if(facb.count(*it)){
vis.insert(*it);
}
}
set<ll> facab = fac(a+b);
for(set<ll>::iterator it=facab.begin();it!=facab.end();it++){
if(!vis.count(*it)){
res++;
}
}
cout<<res<<"\n";
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
euler(1e6);
int t=1;
cin>>t;
while(t--){
solve();
}
return 0;
}
K 游乐场选址
模板题
Floyd算法 、枚举所有俩个游乐场的位置求出最小值即可
#include <bits/stdc++.h>
#define INT64_MAX 0x7fffffffffffffff
#define ll long long
using namespace std;
void floyd_warshall(int V, vector<vector<int> >&d){
for(int k=1;k<=V;k++){
for(int i=1;i<=V;i++){
for(int j=1;j<=V;j++){
d[i][j] = min(d[i][j],d[i][k]+d[k][j]);
}
}
}
}
void solve(){
int n,m;
cin>>n>>m;
vector<vector<int> >g(n+1,vector<int>(n+1,0x3f3f3f3f));
vector<int>person(n+1);
for(int i=1;i<=n;i++){
cin>>person[i];
g[i][i]=0;//自己到自己的时间花费为0
}
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
g[u][v] = min(g[u][v],w);
g[v][u] = min(g[v][u],w);
}
floyd_warshall(n,g);
ll ans = INT64_MAX;
//枚举
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j)continue;
ll res=0;
for(int k=1;k<=n;k++){
res+= 1LL*(min(g[k][i],g[k][j]))*person[k];
//cout<<res<<"\n";
}
ans = 1LL*min(ans,res);
}
}
cout<<ans <<"\n";
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int t=1;
// cin>>t;
while(t--){
solve();
}
return 0;
}