A
前言
t
a
g
:
tag :
tag: 简单
暴力判断
筛法预处理
题意 :
给定
x
x
x找到两个素数
a
,
b
a,b
a,b
满足 :
a
≤
b
a \le b
a≤b
a
×
b
=
x
a ×b = x
a×b=x
思路 :
本来以为是数学推公式的题,虽然数据范围很小
可是发现题解很多大佬都是暴力枚举直接判断, y 总 y总 y总的那种方法又不适用
所以我这里直接 埃筛预处理处理来用 m a p map map直接判断
一开始没想到直接暴力判断,时间复杂度也是够的,哈哈
code :
int st[N],primes[N],cnt;
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (st[i]) continue;
primes[cnt ++ ] = i;
mp[i] = 1;
for (int j = i + i; j <= n; j += i)
st[j] = true;
}
}
void solve(){
get_primes(998);
ll x;cin>>x;
for(int i = 0 ; i < cnt ;i ++ ){
int temp = primes[i];
if(x%temp == 0 ){
if(mp[temp] == 1){
cout<<temp<<" "<<x/temp<<endl;
return;
}
}
}
}
B
前言
t
a
g
:
tag :
tag: 思维题
数组操作
题意 :
思路 :
显然对于第一种操作,因为他是对单独的一个所以我们可以考虑最后操作
我们先考虑如何进行第二种操作。因为第一种操作针对偶数,所以我们尽可能的用第二
种操作将所有数变为第一种操作可操作的数。
因为考虑改变了的状态不能再改变,所以这里是 a [ i ] − − , a [ i + 1 ] − − a[i]--,a[i+1]-- a[i]−−,a[i+1]−−而不是 a [ i − 1 ] − − a[i-1]-- a[i−1]−−
code :
int n,a[N];
void solve(){
cin>>n;
for(int i = 1;i<=n;i ++ ) cin>>a[i];
Fup(i,1,n-1){
if(a[i]&1){
a[i] -- ,a[i+1] --;
}
}
Fup(i,1,n){
if(a[i]&1 || a[i] < 0){
NO
return;
}
}
YES
}
C
前言
t
a
g
:
tag :
tag:模板题
树的直径
传送门 :
题意 :
给定一棵树,点权
w
i
w_i
wi,边权
c
i
c_i
ci。每次经过一个点总能量增加
w
i
w_i
wi,经过一条边总能量减少
c
i
c_i
ci
当总能量到达负数的时候,不能进行任意操作。询问最终能量剩余最大的简单路径。
思路 :
有这种限制遍历的题。我们一般从叶子节点考虑
我们设 f [ u ] f[u] f[u]表示当前节点能获得的最大能量
当 f [ v ] − c [ u − v ] ≥ 0 f[v] -c[u-v] \ge 0 f[v]−c[u−v]≥0的时候我们转移到父节点
因为父节点可以向两边延深,所以我们如同求树的直径那样的做法即可
code :
struct node{
int to,val;
};
vector<node> g[N];
int w[N];
int n,d;
int d1[N],d2[N],f[N];
void dfs(int u, int fa)
{
d1[u] = d2[u] = 0 ;
for(auto x : g[u]){
int v = x.to;
if (v == fa) continue;
dfs(v, u);
if(f[v] - x.val >= d1[u]){
d2[u] = d1[u];
d1[u] = f[v] - x.val;
}else if(f[v] - x.val >= d2[u]){
d2[u] = f[v] - x.val;
}
}
d = max(d,w[u] + d1[u] + d2[u]);
f[u] = w[u] + d1[u];
}
void solve(){
cin>>n;
Fup(i,1,n) cin>>w[i];
Fup(i,1,n-1){
int u,v,c;cin>>u>>v>>c;
g[u].pb({v,c});
g[v].pb({u,c});
}
dfs(1,-1);
cout<<d<<endl;
}
signed main(){
IOS
CIT
COT
//int t;cin>>t;while(t--)
solve();
return 0 ;
}