第一题
这个主要是考察进制之间的转换 (1MB=1024KB=1024*1024B 1B=8bit)
cpp
#include <iostream>
using namespace std;
int main()
{
cout<<(long long)256*1024*1024*8/32;
return 0;
}
第二题
看这个题目我们可以看到有n个卡片--》可以分配1+2+...+n=(n+1)*n/2个人
所以就是一个找规律的题目
cpp
#include<iostream>
using namespace std;
typedef long long ll;
int main()
{
ll n;
cin >> n;
ll k = 0;
while(k * (k + 1) / 2 < n)
{
k++;
}
cout << k << endl;
return 0;
}
第三题
其实就是找斜率或者截距不一样的就行--》但是太复杂了我写不出来,我写出来了结果只考虑了斜率(no)
cpp
#include<iostream>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a % b);
}
int main()
{
int rows = 20, cols = 21;
set<pair<pair<int,int>, pair<int,int>>> lines;
for(int x1 = 0; x1 < rows; x1++)
{
for(int y1 = 0; y1 < cols; y1++)
{
for(int x2 = x1; x2 < rows; x2++)
{
for(int y2 = (x1 == x2 ? y1 + 1 : 0); y2 < cols; y2++)
{
int dx = x2 - x1;
int dy = y2 - y1;
// 化简斜率
int g = gcd(abs(dx), abs(dy));
dx /= g;
dy /= g;
if(dx < 0 || (dx == 0 && dy < 0))
{
dx = -dx;
dy = -dy;
}
// 计算截距
if(dx == 0) // 垂直线
{
lines.insert({{0, 1}, {x1, 1}});
}
else
{
int num = y1 * dx - x1 * dy;
int den = dx;
int g2 = gcd(abs(num), abs(den));
num /= g2;
den /= g2;
if(den < 0)
{
num = -num;
den = -den;
}
lines.insert({{dy, dx}, {num, den}});
}
}
}
}
}
cout << lines.size() << endl;
return 0;
}
第四题
我写了个暴搜结果因为那个那个数据太大了,暴搜根本不行啊啊啊啊哼
第五题
这个题目考察的主要就是最短路径求解--》dijkstra算法+最大公因数求解-->就是模板题
cpp
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
typedef pair<int,int> PII;
const int N=2025,M=2022*21*2;
const int INF=0x3f3f3f3f;
int gcd(int a,int b)
{
return (b==0)?a:gcd(b,a%b);
}
int lcm(int a,int b)
{
return a*b/gcd(a,b);
}
int h[N],e[M],ne[M],w[M],idx;
int dist[N];
bool st[N];
int n=2021;
void add(int a,int b,int c)
{
e[idx]=b;
w[idx]=c;
ne[idx]=h[a];
h[a]=idx++;
}
int dijkstra()
{
memset(dist,0x3f,sizeof dist);
dist[1]=0;
priority_queue<PII,vector<PII>,greater<PII>> heap;
heap.push({0,1});
while(!heap.empty())
{
auto t=heap.top();
heap.pop();
int ver=t.second;
int distance=t.first;
if(st[ver])continue;
st[ver]=true;
for(int i=h[ver];i!=-1;i=ne[i])
{
int j=e[i];
if(dist[j]>distance+w[i])
{
dist[j]=distance+w[i];
heap.push({dist[j],j});
}
}
}
return dist[n];
}
int main()
{
memset(h,-1,sizeof h);
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n&&j-i<=21;j++)
{
int w=lcm(i,j);
add(i,j,w);
}
}
int ans=dijkstra();
cout<<ans<<endl;
return 0;
}
第六题
这个就是时间转换,没什么技巧就直接转换就行了
cpp
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
ll t;
int main()
{
cin>>t;//ms
t=t/1000;//s
ll h=t/3600;//xiaoshi
h=h%24;
ll m=t/60;
m=m%60;
t=t%60;
t=t%60;
printf("%02d:%02d:%02d",h,m,t);
return 0;
}
第七题
一眼就是要用dfs暴力搜索--》又tle了哈哈哈哈拿到一般的分
暴搜--》记忆化搜索--》动态规划
这个就是看选还是不选--》然后选的话再看到底是与之前方向一样还是不一样
--》tle版
cpp
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
//往左放,往右放,放或者不放
const int N=110,M=100010;
int n;
int a[N];
bool used[M];
ll res=0;
//选或者不选
void dfs(int x,ll sum)
{
if(x>n)
{
if(!used[sum]&&sum>0)
{
used[sum]=true;
res++;
}
return;
}
dfs(x+1,sum);//不选
//选
//相同方向
dfs(x+1,sum+a[x]);
//不同方向
dfs(x+1,abs(sum-a[x]));
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
dfs(1,0);
cout<<res<<endl;
return 0;
}
记忆化搜索解决
cpp
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
//往左放,往右放,放或者不放
const int N=110,M=200010;
int n;
int a[N];
bool used[M];
ll res=0;
map<pair<int,int>,bool> mem;
void dfs(int x,int sum)
{
if(x>n)
{
if(sum>0&&!used[sum])
{
used[sum]=true;
res++;
}
return;
}
if(mem[{x,sum}])return;
mem[{x,sum}]=true;
dfs(x+1,sum);
dfs(x+1,sum+a[x]);
dfs(x+1,abs(sum-a[x]));
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
dfs(1,0);
cout<<res<<endl;
return 0;
}
动态规划版--》
cpp
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 110, M = 200010;
int n;
int a[N];
bool dp[M]; // dp[i] 表示重量 i 能否被称出
int total;
int main()
{
cin >> n;
for(int i = 1; i <= n; i++)
{
cin >> a[i];
total += a[i];
}
dp[0] = true;
for(int i = 1; i <= n; i++)
{
bool temp[M]={false};
for(int j=0;j<=total;j++)
{
if(dp[j])
{
temp[j]=true;
temp[j+a[i]]=true;
temp[abs(j-a[i])]=true;
}
}
for(int j=0;j<=total;j++)
{
if(temp[j])
{
dp[j]=true;
}
}
}
int res = 0;
for(int i = 1; i <= total; i++)
{
if(dp[i]) res++;
}
cout << res << endl;
return 0;
}
第八题
就只能过那个小样例哈哈哈哈哈拿了4分
4分版--》用邻接矩阵存储的
cpp
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll n;
int dp[15][15];
int main()
{
cin>>n;
for(int i=1;i<=n+1;i++)
{
dp[i][1]=1;
dp[i][i]=1;
}
ll x=-1,y=-1;
if(n==1)
{
cout<<1<<endl;
return 0;
}
for(int i=3;i<=n+1;i++)
{
for(int j=2;j<i;j++)
{
dp[i][j]=dp[i-1][j-1]+dp[i-1][j];
if(dp[i][j]==n)
{
x=i;
y=j;
break;
}
}
if(x!=-1)break;
}
ll cnt=0;
for(int i=1;i<=x-1;i++)
{
cnt+=i;
}
cnt+=y;
cout<<cnt<<endl;
return 0;
}
第九题
这个题直接用sort做,可以拿到15分👍
主要是这个题得知道怎么用sort实现逆序--》sort(a,a+n,greater<>)
cpp
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=100010;
int n,m;
int a[N];
void jiangxu(int x)
{
sort(a+1,a+1+x,greater<int>());
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
a[i]=i;
}
while(m--)
{
int x,y;
cin>>x>>y;
if(x==0)
{
jiangxu(y);
}
else if(x==1)
{
sort(a+y,a+1+n);
}
}
for(int i=1;i<=n;i++)
{
cout<<a[i];
if(i<n)cout<<' ';
}
return 0;
}