牛客算法周周练2
作者:互联网
链接:https://ac.nowcoder.com/acm/contest/5203/A
来源:牛客网
题目描述 (暴力)
为了得到一个数的"相反数",我们将这个数的数字顺序颠倒,然后再加上原先的数得到"相反数"。例如,为了得到1325的"相反数",首先我们将该数的数字顺序颠倒,我们得到5231,之后再加上原先的数,我们得到5231+1325=6556.如果颠倒之后的数字有前缀零,前缀零将会被忽略。例如n = 100, 颠倒之后是1. 直接暴力就可;#include<iostream> #include<algorithm> using namespace std; int n; int main() { cin>>n; int k=0,m=n; while(m) { k=k*10+m%10; m=m/10; } cout<<k+n; return 0; }
链接:https://ac.nowcoder.com/acm/contest/5203/B
来源:牛客网
题目描述
Listening to the music is relax, but for obsessive(强迫症), it may be unbearable. HH is an obsessive, he only start to listen to music at 12:00:00, and he will never stop unless the song he is listening ends at integral points (both minute and second are 0 ), that is, he can stop listen at 13:00:00 or 14:00:00,but he can't stop at 13:01:03 or 13:01:00, since 13:01:03 and 13:01:00 are not an integer hour time. Now give you the length of some songs, tell HH whether it's possible to choose some songs so he can stop listen at an integral point, or tell him it's impossible. Every song can be chosen at most once. 看到这道题的时候,就是选出几个数使得其是3600的倍数,感觉用dp,但是吧,感觉用二维;担心数据过不了;看了题解,原来是mod 3600; 链接:https://ac.nowcoder.com/acm/contest/5203/C来源:牛客网
#include<bits/stdc++.h> using namespace std; int t,n,a[110000]; int dp[3600]; int m[110000]; int main() { cin>>t; while(t--) { memset(dp,0,sizeof(dp)); cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n&&!dp[0];i++) { int cnt=0; for(int j=1;j<3600;j++) { if(dp[j]) { m[++cnt]=(j+a[i])%3600; }//需要先放入m数组中,如果直接dp,会重算 } for(int i=1;i<=cnt;++i) dp[m[i]]=1; dp[a[i]%3600]=1; } if(dp[0]) printf("YES\n"); else printf("NO\n"); } }
题目描述 (数学)
多次查询[l,r]范围内的完全平方数个数
定义整数x为完全平方数当且仅当可以找到整数y使得y*y=x
一开始想的是找出所有完全平方数,用前缀和,但是内存超限~~。看了下数据,1~1e9的完全平方数并不多。then 还是根据之前的思路,因为内存超限,怎么才能使内存减小??(大脑是个神奇的东西),昨天写了数码这一题,看了篇题解,说可以将区间分成【l,r】分成【1,r】和【1,l-1】,按照这个思路,只需要求出1~r的完全平方数,再用前缀和即可。预处理,发现1~10000的完全平方数为100=sqrt(r),可以想一下,因为100*100为10000,100之前的数的平方都比10000小,之后的数都大于10000。所以l~r的完全平方数为(ll)sqrt(r)-(ll)sqrt(l-1). 注意0,l==0的时候特判即可;(倭瓜技术太烂,正在成长,表示虽然题简单,但还是高兴自己能做出来~~)
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define ll long long
int main()
{
ll l,r;
ll t;
cin>>t;
while(t--){
cin>>l>>r;
ll ans=0,ans1=0;
if(l==0) cout<<(ll)sqrt(r)+1<<endl;
else cout<<(ll)sqrt(r)-(ll)sqrt(l-1)<<endl;
}
return 0;
}
链接:https://ac.nowcoder.com/acm/contest/5203/D
来源:牛客网
题目描述 (树形结构+dp优化)
小H正在玩一个战略类游戏,她可以操纵己方的飞机对敌国的N座城市(编号为1~N)进行轰炸敌国的城市形成了一棵树,小H会依次进行Q次轰炸,每次会选择一个城市A进行轰炸,和这座城市距离不超过2的城市都会受损(这里距离的定义是两点最短路径上的边数),轰炸结束后,小H还想知道当前城市A受损的次数
作为游戏的开发者之一,你有义务回答小H的问题 表示只想到了dfs,但数据只过了90%,所以需要看dfs中是否重复搜索; 对于点x,轰炸一次,其儿子,孙子,父亲,祖父,以及自身,兄弟都需要加一,dp【x】【0、1、2】,代表本身,1代表儿子,2代表孙子;则对其进行轰炸, dp【f【x】】【0】(父亲自身加1),dp【f【x】】【1】表示x的兄弟以及自身,加一,dp【f【f【x】】】【0】祖父自身+1,dp【x】【1,2】分别加1;
#include<iostream> #include<algorithm> using namespace std; #define maxn 1100000 int n,head[maxn],q,cnt,f[maxn],tree[maxn][3]; struct edge{ int nx,to; }edge[maxn*2]; void dfs(int u,int fa,int depth) { f[u]=fa; for(int i=head[u];i;i=edge[i].nx) { int v=edge[i].to; if(v!=fa) { dfs(v,u,depth+1); } } } void add(int u,int v) { edge[++cnt].nx=head[u]; edge[cnt].to=v; head[u]=cnt; } int main() { cin>>n>>q; for(int i=1;i<n;i++) { int x,y; cin>>x>>y; add(x,y),add(y,x); } dfs(1,0,0); while(q--) { int a; cin>>a; tree[f[a]][0]++,tree[f[a]][1]++; tree[f[f[a]]][0]++; tree[a][1]++; tree[a][2]++; cout<<tree[a][0]+tree[f[a]][1]+tree[f[f[a]]][2]<<endl; } }
链接:https://ac.nowcoder.com/acm/contest/5203/E
来源:牛客网
标签:00,int,ll,cin,周周练,牛客,算法,include,dp 来源: https://www.cnblogs.com/Showend/p/12706961.html