赛码网3月31号模拟试题(C++)

写在前面:

闲来无事把赛码网的几个模拟测试做了下,其中一些解题思路即感悟记录于此。

进入正题:

概要: 总共2个题,一个小时的时间安排。题目难度适中偏简单。

第一题 小赛打车

题目描述

小赛要去位于 A 市的小码家。小赛来到 A 市的车站,买了一张 A 市的地图,他发现这里的地形非常的复杂。A 市的街道一共有 N 个路口,M 条道路,每条道路连接着两个路口,并且有各自的长度。目前,小赛所在的车站位于编号为 1 的路口,而小码家所在的路口编号为 N,小赛准备打出租车去,当然,路程越小,付的钱就越少。问题摆在眼前:请帮助小赛寻找一条最短路径,使得他可以花最少的钱到达小码家。


大概这就是典型的最短路径算法吧,节点个数也不多,但是也不少,想用什么全排列一类的枚举肯定是会超时的,所以可以使用dijkstra算法来做,时间复杂度O(n*n)。

#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <bits/stdc++.h>

using namespace std;

int dijkstra(vector<vector<int>>& table, vector<bool>& marks, vector<int>& dist, int n) {
    while(1){
      int idx = -1, min_dist = INT_MAX;
      for(int i=0;i<n;i++){
        if(marks[i])  continue;
        if(dist[i]<min_dist){
          min_dist = dist[i];
          idx = i;
        }
      }
      if(idx==n-1)  return dist[idx];
      marks[idx] = true;
      for(int i=0;i<n;i++){
        if(marks[i])  continue;
        if(table[idx][i]<INT_MAX&&dist[idx]+table[idx][i]<dist[i])  dist[i] = dist[idx]+table[idx][i];
      }
    }
}

int main() {
	int n = 0, m = 0;
	cin >> n >> m;
	vector<vector<int>> table(n,vector<int>(n,INT_MAX));
	for (int i = 0; i<m; i++) {
		int a = 0, b = 0, c = 0;
		cin >> a >> b >> c;
    table[a-1][b-1] = c; table[b-1][a-1] = c;
	}
	vector<bool> marks(n, false);
  vector<int> dist(n,INT_MAX);dist[0] = 0;
	int result = dijkstra(table, marks, dist, n);
	cout << result << endl;
	return 0;
}

/*#include <bits/stdc++.h>
using namespace std;
int main(){
  int n,m;
  cin>>n>>m;
  vector<vector<int> > mp(n+1,vector<int>(n+1,INT_MAX));
  int p1,p2,l;
  for(int i=0;i<m;++i){
    cin>>p1>>p2>>l;
    mp[p1][p2]=l;
    mp[p2][p1]=l;
  }
  vector<int> dis(n+1,INT_MAX);
  vector<bool> visited(n+1,false);
  dis[1]=0;
  while(1){
    int index=-1;
    int mind=INT_MAX;
    for(int i=1;i<=n;++i){
      if(visited[i])continue;
      if(dis[i]<mind){
        mind=dis[i];
        index=i;
      }
    }
    if(index==n){
      cout<<dis[index]<<endl;
      return 0;
    }
    visited[index]=true;
    for(int i=1;i<=n;++i){
      if(visited[i])continue;
      if(mp[index][i]<INT_MAX&&dis[i]>dis[index]+mp[index][i]){
        dis[i]=dis[index]+mp[index][i];
      }
    }
  }
  return 0;
}
*/


第二题 完美数

题目描述

我们称一个正整数n是完美数,如果n的所有因子的平方和f(n)是一个完全平方数。

例如n=10,那么f(n)=1+4+25+100=130,所以10不是一个完美数。

请求出小于n的所有完美数的和。

对于40%的数据n<=10000

对于100%的数据n<=1000000

这道题也是暂时想不出有什么更优的方法,唯一能想到的就是按规则来枚举,最后也是过了。

#include <iostream>
#include <cmath>

using namespace std;

/*bool check(int num){
  int ret = 0;
  for(int i = 1; i <= num / 2; i ++)
    if(num % i == 0)
      ret += i * i;
  ret += num * num;
  int x = sqrt((double)ret);
  if(x * x == ret)
    return true;
  return false;
}*/

bool isValid(int n){
  long long ans = n*n;
  for(int i=1;i<=n/2;i++){
    if(n%i==0)  ans += i*i;
  }
  long long x = sqrt(ans);
  if(x*x==ans)  return true;
  else return false;
}

int main(){
  int n;
  cin >> n;
  long long ans = 0;
  for(int i=1;i<=n;i++){
    if(isValid(i))  ans += i;
  }
  cout << ans << endl;
  return 0;
}


总结:

找工作路漫漫,但求不忘初心,回首对得起走过的路。

代码地址: [luuuyi/some_companies_test]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值