Tag
枚举
题意
有 0
到 9
的卡片,每种有 2021
张,一张卡片仅能用一次,从 1
开始拼,输出最大拼出的数
#include
using namespace std;
int a[10];
int solve(){
for(int i=1;;i++){
int x=i;
while(x){
int t=x%10;
if(a[t]==0)return i-1;
a[t]--;
x/=10;
}
}
}
int main(void){
for(int i=0;i<10;i++)a[i]=2021;
cout<<solve()<<endl;
return 0;
}
Tag
枚举
数学
题意
给定平面上 20 × 21
个整点 {(x, y)|0 ≤ x < 20, 0 ≤ y < 21, x ∈ Z, y ∈ Z}
,连接并贯穿两个点形成直线,输出一共能形成的直线数量
分析
需要特殊处理与坐标轴平行的直线
#include
#include
using namespace std;
set<pair<double,double>> s;
set<int> px,py;
void solve(double x1,double x2,double y1,double y2){
if(y1==y2){
py.insert(y1);
return;
}
if(x1==x2){
px.insert(x1);
return;
}
double k,b;
k=(y1-y2)/(x1-x2);
b=(x1*y2-x2*y1)/(x2-x1);
s.insert({k,b});
}
int main(void){
for(double x1=0;x1<20;x1++)
for(double y1=0;y1<21;y1++)
for(double x2=0;x2<20;x2++)
for(double y2=0;y2<21;y2++)
solve(x1,x2,y1,y2);
cout<<s.size()+px.size()+py.size()<<endl;
return 0;
}
Tag
枚举
题意
堆长方体,体积为 2021041820210418
,有多少种整数解
#include
using namespace std;
typedef long long ll;
ll res,n=2021041820210418;
ll a[150],idx;
int main(void){
for(int i=1;i<=n/i;i++){
if(n%i==0){
a[idx++]=i,a[idx++]=n/i;
if(i==n/i)idx--;
}
}
for(int i=0;i<idx;i++)
for(int j=0;j<idx;j++)
for(int k=0;k<idx;k++)
if(a[i]*a[j]*a[k]==n)res++;
cout<<res<<endl;
return 0;
}
Tag
Dijkstra最短路
gcd/lcm
题意
由 2021
个结点组成的图,编号 1~2021
,若 a-b
的差小于等于 21
则 a
与 b
相连的无向边长度为两者的最小公倍数,反之不存在相连的边,结点 1
和结点 2021
之间的最短路径长
#include
#include
#include
using namespace std;
typedef pair<int,int> PII;
const int N=2022,M=2*N*43;
int idx,h[N],e[M],ne[M],w[M];
int d[N];
bool st[N];
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a*b/gcd(a,b);}
void add(int a,int b,int c){
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
int Dijkstra(){
priority_queue<PII,vector<PII>,greater<PII>> heap;
heap.push({0,1});
d[1]=0;
while(heap.size()){
auto t=heap.top();
heap.pop();
int ver=t.second,dis=t.first;
if(st[ver])continue;
st[ver]=1;
for(int i=h[ver];i!=-1;i=ne[i]){
int j=e[i];
if(d[j]>d[ver]+w[i]){
d[j]=d[ver]+w[i];
heap.push({d[j],j});
}
}
}
return d[2021];
}
int main(){
memset(h,-1,sizeof h);
memset(d,0x3f,sizeof d);
for(int i=1;i<N;i++)
for(int j=1;j<N;j++)
if(abs(i-j)<=21){
int t=lcm(i,j);
add(i,j,t),add(j,i,t);
}
cout<<Dijkstra()<<endl;
return 0;
}
Tag
进制
题意
256MB
内存空间能存放多少个 32
位二进制整数,不考虑程序占用的空间和维护内存需要的辅助空间
#include
using namespace std;
int main(){
cout<<1ll*256*1024*1024*8/32<<endl;
return 0;
}
Tag
dp
题意
一架天平,n
个砝码,质量分别为 w[i]
,砝码可以放在天平两端,求一共能称出多少种不同的质量
#include
using namespace std;
const int N=101,M=1e5+1;
int n,s,res;
int a[N];
bool dp[N][M]; // dp[i][j] 前 i 个砝码能称出 j
int main(void){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i],s+=a[i];
dp[0][0]=1;
for(int i=1;i<=n;i++)
for(int j=0;j<=s;j++)
if(dp[i-1][j]||dp[i-1][j+a[i]]||dp[i-1][abs(j-a[i])])
dp[i][j]=1;
for(int i=1;i<=s;i++)
if(dp[n][i])res++;
cout<<res<<endl;
return 0;
}
题意
给定一个含 (
和 )
的字符串,求使得插入括号最少的且使得括号字符串合法的有多少种
Tag
数学
题意
输入为 1970 年 1 月 1 日 00:00:00
开始经过的毫秒数,输出为 HH:MM:SS
格式的时间
#include
using namespace std;
typedef long long ll;
const int m=60,h=m*60,d=h*24;
int main(void){
int T;cin>>T;
while(T--){
ll x;cin>>x;
x/=1000;
int hh,mm;
x%=d;
hh=x/h,x%=h;
mm=x/m,x%=m;
printf("%02d:%02d:%02d\n",hh,mm,x);
}
return 0;
}
Tag
组合数
题意
给出 t
个 n
满足 1 ≤ n ≤ 1e9
,分别求杨辉三角形中第一次出现 n
的序号
分析
杨辉三角形左右对称,斜着第一个数是 C(i, 2i)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DVYNOZQV-1679052944937)(null)]
1 ---> C(0, 0)
1
1 2 ---> C(1, 2)
1 3
1 4 6 ---> C(2, 4)
1 5 10
1 6 15 20 ---> C(3, 6)
#include
using namespace std;
typedef long long ll;
int x;
ll C(int a,int b){
ll res=1;
for(int i=b,j=1;j<=a;i--,j++){
res=res*i/j;
if(res>x)return res;
}
return res;
}
int main(void){
int T;cin>>T;
while(T--){
cin>>x;
for(int i=16;;i--){ // C(16,32) < 1e9 < C(17,34)
int l=2*i,r=max(x,l);
while(l<r){
int mid=l+r>>1;
if(C(i,mid)>=x)r=mid;
else l=mid+1;
}
if(C(i,r)==x){
cout<<1ll*(r+1)*r/2+i+1<<endl;
break;
}
}
}
return 0;
}
题意
n
个数 a[i] = i
,进行 m
次操作,每次输入 p[i]
q[i]
p[i] = 0
时 a[1] .. a[q[i]]
降序排列
p[i] = 1
时 a[q[i]] .. a[n]
升序排列
分析
此题使用 sort
会 TLE
,仅能够 AC 60%