D. Tom的战力问题
Tom被斯派克揍了TAT。
Tom下定决心要战胜斯派克。
但是在战胜最强的斯派克之前,Tom要先打败其他的狗。为此,他打算先收集一下信息。
现在Tom在了得到了一些关于战斗力的小道消息,例如X号狗狗的战力比Y号狗狗的战力高S点。
Tom想知道利用这些消息,能不能判断出某两只狗之间的战力高低?高多少?
输入格式
第一行包含三个整数N,M和Q。N表示狗总数,M表示Tom知道消息的总数,Q表示小Tom想询问的数量。
以下M行每行三个整数,X,Y和S。表示X号狗的战力比Y号狗的战力高S点。
以下Q行每行两个整数,X和Y。表示Tom想知道X号狗的战力比Y号狗的战力高几点。
2≤N≤1000
1≤M,Q≤N
1≤X,Y≤N
−1000≤S≤1000
数据保证没有矛盾。
输出格式
对于每个询问,如果不能判断出X比Y高几点输出−1。否则输出X比Y高多少战力点。
样例
10 5 3 1 2 10 2 3 10 4 5 -10 5 6 -10 2 5 10 1 10 1 5 3 5
-1 20 0
其实就是一个简单的BFS问题。题目中问两个狗之间的站力相差多少,我们可以看成路径问题即A到B的距离为C,B到A的距离为-C,然后跑图,不可到大的话输出-1
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> using namespace std; const int N=1e3+7; int n,m,q; struct stu{ int a,b; }; vector<stu >ve[N]; int mark[N]; bool check=false ; int f=-1; void bfs(int x,int y){ memset(mark,0,sizeof(mark)); queue<stu >que; que.push({x,0}); mark[x]=1; while(que.size()){ stu aa=que.front(); que.pop(); // cout<<aa.a<<endl; if(aa.a==y){ f=aa.b; break; } for(int i=0;i<ve[aa.a].size();i++){ if(mark[ve[aa.a][i].a]==0){ mark[ve[aa.a][i].a]=1; que.push({ve[aa.a][i].a,aa.b+ve[aa.a][i].b}); } } } } int main(){ scanf("%d%d%d",&n,&m,&q); int x,y,z; for(int i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); ve[x].push_back({y,z}); ve[y].push_back({x,-z}); } while(q--){ f=-1; int x,y; scanf("%d%d",&x,&y); bfs(x,y); printf("%d ",f); } return 0; }
E Tom的函数求值
众所周知,Tom不会递归,但是今天他突然顿悟了!并且凭借自己的能力写出了下面这段代码:
int F(int m,int n)
{
if(!m)
return n+1;
if(!n&&m)
return F(m-1,1);
if(m&&n)
return F(m-1,F(m,n-1));
}
现在,他想让你根据这个函数来解决问题
输入格式
单组输入,每组一行,有两个整数m和n(0≤m≤3,0≤n≤27)
输出格式
请输出上面代码的运行结果
样例
1 1
3
0 1
2
提示
如果不知道怎么做的话,不妨试试直接把代码复制粘贴进去吧٩̋(ˊ•͈ ꇴ •͈ˋ)و
对于这种类型的题目,我们可以先运行一下它给出的代码,然后输出一些值,在找规律。
//int F(int m,int n) //{ // if(!m) // return n+1; // if(!n&&m) // return F(m-1,1); // if(m&&n) // return F(m-1,F(m,n-1)); //} #include<iostream> #include<cstdio> using namespace std; typedef long long ll; // m==0 n+1; // m==1 2 3 4 // m==2 3 5 7 // m==3 5 13 29 ll f(ll x){ if(x==0) return 5; else return 2*f(x-1)+3; } int main(){ ll a,b; scanf("%lld %lld",&a,&b); if(a==0) printf("%d",b+1); else if(a==1) printf("%d ",b+2); else if(a==2) printf("%d ",2*b+3); else if(a==3) printf("%lld ",f(b)); return 0; }
FTom的约会
XX协会又要迎来新的成员了。
这次的妹子颇多,足足有n人之多(1≤n≤106),她们每个人的学号都是1018 内的一个正整数。
Jerry 早早地就掌握了她们每个人的学号,并且知道她们之中有一个人和Tom约会去了!
Jerry 统计了在场所有妹子的学号,他想知道,哪个人没来?
输入格式
第一行是一个整数n,代表一共有n只妹纸
以下n行每行一个整数,代表每只妹纸的学号
接下来一个空行
以下n−1行每行一个整数,代表每只来了的妹纸的学号
输出格式
输出没来的妹纸的学号。
样例
3 10061061 10061023 10061201 10061023 10061201
10061061
提示
开头别想着抢一血,稳着跟榜做题,很多队伍过的题自己卡住了别慌,肯定不是特别难的算法,多换几个思路,上个厕所调整一下状态,总之,心态要好~
~~ 以上都是废话 ~~
看到这个题目,觉得用map比较好,但是TLE了,,用map没TLE的是卡过去的,这里可以开个两个数组,存完值后进行排序,找到第一个不向等的,就可以退出了,
也可以用无序字典
代码1:
#include<iostream> #include<cstdio> #include<unordered_map> using namespace std; typedef long long ll; unordered_map<ll,int >mp; unordered_map<ll,int>::iterator it; int main(){ int t; cin>>t; int t1=t-1; while(t--){ ll x1; scanf("%lld",&x1); mp[x1]++; } while(t1--){ ll y; scanf("%lld",&y); mp[y]++; } for(it=mp.begin();it!=mp.end();it++){ if(it->second==1){ printf("%lld ",it->first); break; } } return 0; }
代码2:
#include<cstdio> #include<algorithm> #include<vector> using namespace std; typedef long long ll; const int N=1e6+7; ll p[N]; ll p2[N]; int main(){ int t; scanf("%d",&t); ll x; for(int i=1;i<=t;i++){ scanf("%lld",&p[i]); } for(int i=1;i<=t-1;i++){ scanf("%lld",&p2[i]); } sort(p+1,p+1+t); sort(p2+1,p2+t); bool f=false ; for(int i=1;i<=t-1;i++){ if(p[i]!=p2[i]){ f=true; printf("%lld",p[i]); break; } } if(!f) printf("%lld",p[t]); return 0; }
G. Tom爬楼梯
Jerry 跑到了二楼,现在Tom面临的是一个n阶的楼梯,由于Tom的腿比较短,因此它一次只能爬1阶或2阶,机智的Jerry破坏掉了m阶楼梯,也就是说Tom无法踩在这m阶楼梯上,现在Tom想知道他有多少种方案能爬到第n阶楼梯。由于答案很大,输出方案数对109+7取模的结果。
输入格式
第一行输入一个T代表有T组输入,对于每组输入:
第一行输入n,m,第二行输入m个数,第i个数ai代表第ai阶楼梯被破坏了。
(1≤T,m≤10,1≤n≤1000,1≤ai≤n)。
输出格式
对于每组输入,输出方案数对109+7取模的结果。
样例
3 1 1 1 8 1 1 10 2 1 2
0 13 0
L. Jerry的食粮
公元9102年,Tom不再追逐Jerry,因为Tom的主人已经从China进口了很多猫粮,并且还有了智能抓老鼠机器。
小Jerry无处可躲,只能露宿街头。Tom不再缺乏食粮,但是可怜的小Jerry仍然还饥肠辘辘。
这一天,小Jerry实在是饿坏了,再不吃点儿东西,他可能就横死街头了,于是,他想到了他的老朋友Tom,
Tom这个糟老头子可是坏得很呀,他给小Jerry出了一个问题,做出来这个问题,小Jerry就能获得糟老头子Tom
赞助的补给!!!只有伟大的团队可以帮得了Jerry,并将获得荣耀之光,你们能帮可怜的Jerry获得补给吗?
给定一个正整数n,求至少两个正整数使得他们的lcm(最小公倍数)为n,且这些正数的和最小,输出这个最小和。
输入格式
第一行一个整数T(1≤T≤1e4)
接下来T行,每行一个正整数n(1≤n≤231−1)
输出格式
输出T行,每行输出”Case #: “(不包括“”),#表示第#组数据,后面跟题目要求的答案,具体输出可参考样例
样例
3 12 10 5
Case 1: 7 Case 2: 7 Case 3: 6
分解质因子,然后记录每个质因子构成的值,最后累加就好了,但是注意,,如果他的质因子个数只有一个,或者他是质数的话直接输出n+1
#include<iostream> #include<cstdio> #include<cmath> using namespace std; typedef long long ll; const int N=1e6+7; int prime[N]={1,1,0}; ll pre[N]; void f_prime(){ int sum=0; for(int i=2;i<=N;i++){ if(prime[i]==0){ pre[sum++]=i; for(int j=i+i;j<=N;j+=i){ prime[j]=1; } } } } int main(){ f_prime(); int t; int k=0; cin>>t; while(t--){ k++; ll n; scanf("%d",&n); ll n1=n; printf("Case %d: ",k); if(n==1){ printf("2 "); continue ; } ll m=sqrt(n+1); ll ans=0; int x=0; for(int i=0;pre[i]<=m;i++){ ll sum=1; if(n%pre[i]==0){ x++; while(n%pre[i]==0){ sum*=pre[i]; n/=pre[i]; } ans+=sum; } } if(n>1){ x++; ans+=n; } if(x>1) { printf("%lld ",ans); } else { printf("%lld ",1+n1); } } return 0; }