1. 空间
签到水题,单位换算
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
cout<<(int)256*1024*1024*8/32<<endl;
return 0;
}
2. 卡片
打表找规律,先存取所有可能的结果
// k种卡片组成 两两组合分给n k*(k+1)/2 >= n
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
vector<int>nums;
signed main()
{
cin>>n;
for(int i=1; i<=1000000; i++) //找出k对应n所有情况
{
nums.push_back(i*(i+1)/2);
}
for(int i=0; i<nums.size(); i++)
{
if(nums[i]>=n)
{
cout<<i+1<<endl;
break;
}
}
return 0;
}
3. 直线
数学知识,对于直线的确定,暴力遍历所有可能,需要特别注意斜率为0的情况
#include <bits/stdc++.h>
#define int long long
using namespace std;
set<pair<int, int>> nums; // 存储坐标
set<pair<double, double>> nums1; // 存储斜率截距
signed main()
{
int n,m;
cin>>n>>m;
// 插入坐标点
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
nums.insert({i, j});
}
}
// 使用迭代器两两组合坐标点,计算斜率和截距
vector<pair<int, int>> points(nums.begin(), nums.end());
for (size_t i = 0; i < points.size(); i++)
{
for (size_t j = i + 1; j < points.size(); j++)
{
int x1 = points[i].first, y1 = points[i].second;
int x2 = points[j].first, y2 = points[j].second;
if (x1 != x2) // 防止除以零
{
double k = 1.0 * (y2 - y1) / (x2 - x1);
double b=1.0*(x1*y2-x2*y1)/(x1-x2);
nums1.insert({k, b});
}
}
}
cout << nums1.size()+n << endl; //20斜率不存在的情况(垂直)
return 0;
}
4. 货物摆放
数学知识,首先求出所有可能的因子情况,最后暴力遍历确定可能的结果,排列
//求出因子总数n 再求三位数全排列
#include<bits/stdc++.h>
#define int long long
using namespace std;
int sum=0;
vector<int>nums;
const int n=2021041820210418;
signed main()
{
for(int i=1; i*i<=n; i++)
{
if(n%i==0)
{
nums.push_back(i);
if(i!=n/i)
{
nums.push_back(n/i);
}
}
}
for(int i=0; i<nums.size(); i++)
{
for(int j=0; j<nums.size(); j++)
{
for(int k=0; k<nums.size(); k++)
{
if(n==(int)nums[i]*nums[j]*nums[k])
{
sum++;
}
}
}
}
cout<<sum<<endl;
return 0;
}
5. 路径
动态规划思想
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
int f[2030]; //遍历出所有情况
memset(f,0,sizeof(f));
for(int i=1;i<=2021;i++)
{
for(int j=i+1;j<=i+21 && j<=2021;j++)
{
if(f[j]==0) f[j]=f[i]+i*j/__gcd(i,j);
else f[j]=min(f[j],f[i]+i*j/__gcd(i,j)); //多条路径到同一点
}
}
cout<<f[2021]<<endl;
return 0;
}
6. 时间显示
签到水题,有两个需要注意点:
1.除法会自动转为浮点运算(所以不要同时操作乘除法)
2.补全前导0的方法:printf("%02d:%02d:%02d\n",h,m,s); 补零两位输出
//1h=3600*1000ms 24h=86400*1000ms
#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,t1=0,day=0,h=0,m=0,s=0;
signed main()
{
cin>>t;
day=t/86400000; //天数,注意:除法会自动转为浮点运算
t1=t%86400000; //剩余毫秒数
h=t1/3600000;
m=t1%3600000/60000;
s=t1%60000/1000;
printf("%02d:%02d:%02d\n",h,m,s);
return 0;
}
7. 砝码称重
不会做,看题解是动态规划实现的,下面是题解代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll N;
ll a[200];
ll summ=0;
ll ans=0;
int dp[200][200000];
//dp[i][j]表示用到前i个砝码,能否称出j重量
//1为可以,0为不可以
int main()
{
// 请在此输入您的代码
cin>>N;
for(int i=1;i<=N;i++){
cin>>a[i];
summ+=a[i];
}
for(int i=1;i<=N;i++){
for(int j=1;j<=summ;j++){//遍历所有可能的重量
dp[i][j]=dp[i-1][j];//继承前一个状态
if(dp[i][j]==0){//如果普通继承下来,发现这个不行呢?
if(j==a[i]) dp[i][j]=1;//如果需要的重量正好就是第i个砝码,那么可以
if(dp[i-1][j+a[i]]==1) dp[i][j]=1;//如果前i-1个能搞出j+a[i]重量,那么把第i个砝码放到另一侧就行
if(dp[i-1][abs(j-a[i])]==1) dp[i][j]=1;//如果前i-1个砝码能搞出abs(j-a[i])重量
//那么把第i个砝码放同侧就行
}
}
}
for(int j=1;j<=summ;j++){
if(dp[N][j]==1) ans++;//遍历,看dp[][]==1的个数,就是答案
}
cout<<ans<<endl;
return 0;
}
8. 杨辉三角形
没做出来,只能过40%,下面给出我的代码(正常人能想到的不用算法的方法)和正确题解(二分)
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
int a[10010][10010];
signed main()
{
cin>>n;
a[1][1]=1;
for(int i=2;i<=10000;i++)
{
for(int j=1;j<=i;j++)
{
a[i][j]=a[i-1][j-1]+a[i-1][j];
}
}
int sign=0;
for(int i=1;i<=10000;i++)
{
for(int j=1;j<=i;j++)
{
sign++;
if(a[i][j]==n)
{
cout<<sign<<endl;
return 0;
}
}
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int n;
int max(int a,int b)
{
if(a>b) return a;
else return b;
}
long long int fact(int a,int b)
{
long long int x=1;
for(int i=a,j=1;j<=b;i--,j++)
{
x=x*i/j;
if(x>n) return x;
}
return x;
}
int find(int k)
{
long long int l=2*k,r=max(n,l);
long long int c;
while(l<r)
{
int mid=(l+r)/2;
if(fact(mid,k)>=n) r=mid;
else l=mid+1;
}
if(fact(r,k)!=n)
{
return 0;
}
else
{
c=(r*(r+1))/2+k+1;
printf("%lld",c);
return 1;
}
}
int main()
{
// 请在此输入您的代码
scanf("%d",&n);
for(int i=16; ;i--)
{
if(find(i)) break;
}
return 0;
}
9. 双向排序
我的代码能过60%,正确题解得使用线段树(不是很会),感兴趣的可以去官方看
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,a[1000010];
signed main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
a[i]=i;
}
while(m--)
{
int p,q;
cin>>p>>q;
if(p==0) //a1...aq降序
{
sort(a+1,a+1+q,greater<int>());
}
else //aq...an升序
{
sort(a+q,a+1+n);
}
}
for(int i=1; i<=n; i++)
{
cout<<a[i]<<" ";
}
return 0;
}