目录
【平方和】
long long;
填空题可以尝试小的数字,判断程序是否正确!
#include<bits/stdc++.h>
using namespace std;
typedef long long ll; //long long
long long ans=0;
//只要含有0,1,2,9都算
int check(int x){
while(x){
int t=x%10; //求余数
if(t==0||t==1||t==2||t==9)
return 1;
x/=10; //求整
}
return 0;
}
int main(){
for(int i=1;i<=2019;i++){
if(check(i)) ans+=i*i;
}
cout<<ans<<endl;
return 0;
}
【数列求值】
同余理论!
可以用Excel确保编程正确!
#include<bits/stdc++.h>
using namespace std;
int main(){
int t1=1, t2=1, t3=1, t4 ;
for(int i=4;i<=20190324;i++){
t4=(t1+t2+t3)%10000;
t1=t2; t2=t3; t3=t4;
}
cout<<t4<<endl;
return 0;
}
【最大降雨量】
思维能力,无需编程!绝!推理题
【迷宫】
#include<bits/stdc++.h>
#include<queue>
#include<string>
using namespace std;
//4行6列
#define ROWS 4
#define COLS 6
//二维数组
string maze[ROWS+2]={
"010000",
"000100",
"001001",
"110000"
};
//4个方向
int dir[4][2]={{1,0},{0,-1},{0,1},{-1,0}}; //D L R U
char dirs[5]="DLRU";
//定义结构体,结点到达的每一个位置
struct node{
int x,y; //X行y列
char pos; //从上一个结点(父节点)到达当前结点所走的方向 DLRU
};
//代表每一个位置有没有走过
int visited[ROWS+2][COLS+2]; //稍微大一些,不能扣 ,0表示未访问过
//队列 node数据
queue<node> Q;
//每个位置[x][y]的父结点(上一个结点)father[x][y]
node father[ROWS+2][COLS+2];
//是否出边界
int in(int tx, int ty){
return (tx>=0&&tx<ROWS&&ty>=0&&ty<COLS);
}
//伸缩函数
void dfs(int x, int y){
if(x==0&&y==0)
return; //找到入口就不再递归下去
else{
dfs(father[x][y].x,father[x][y].y);
cout<<father[x][y].pos; //因为是在回退时输出“路径”(上的字符) ,所以应该在这里输出
}
}
int main(){
node start, now, next; //定义结点,起始结点,当前结点,下一个结点
int i, tx, ty; //走到(x,y) 的下一个坐标 (tx,ty)
start.x =0; start.y=0;//构造起始结点
Q.push(start);
visited[0][0]=1; //进行入队列
while(!Q.empty()){
now=Q.front(); //取出当前结点
Q.pop();
if(now.x==ROWS-1&&now.y==COLS-1) break;
for(i=0; i<4;i++){ //检查4个方向
tx=now.x+dir[i][0];
ty=now.y+dir[i][1];
if(in(tx,ty)&&maze[tx][ty]=='0'&&visited[tx][ty]==0){
visited[tx][ty]=1;
father[tx][ty].x=now.x;
father[tx][ty].y=now.y;
father[tx][ty].pos=dirs[i];
next.x=tx;
next.y=ty;
Q.push(next); //入队列
}
}
}
dfs(ROWS-1,COLS-1);
return 0;
}
【RSA解密】
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//扩展欧几里得求逆元(a和b互质)
ll ext_gcd(ll a, ll b, ll& x, ll&y){
int t, ret;
if(!b){ //b==0
x=1, y=0;
return a;
}
ret=ext_gcd(b, a%b, x, y);
t=x, x=y, y=t-a/b*y; //x是a对模b的逆元,y是b对模a的逆元
return ret;
}
//求(x*y)%p (快速乘,防止爆long long)
inline ll mul(ll x, ll y, ll p){
ll z=(long double)x /p*y;
ll res=(unsigned long long)x*y-(unsigned long long)z*p;
return (res+p)%p;
}
//fpm 快速幂 求X=C^e mod n 并返回X
ll fpm(ll C, ll e, ll n){
C%=n;
ll ans=1;
for(; e; e>>=1, C=mul(C,C,n)) //e>>=1:e 右移一位并赋值给e,即 e/=2
if(e&1) (ans=mul(ans, C,n))%=n; //& 按位与?
return ans;
}
//C=20190324, e=823816093931522017, n=1001733993063167141
ll power(ll C, ll e, ll n){ //求X=C^e mod n 并返回X
ll i, ans=1;
for(i=1; i<=e; i++)
ans=(ans*C)%n;
return ans;
}
int main() {
ll n=1001733993063167141, d=212353, p, q;
//暴力枚举求p,q
for(ll i=3; i*i<n; i+=2){
if(n%i==0){ //n%i==0 首个满足if条件的i一定为素数
p=i; q=n/i; break;
}
}
// cout<<"p="<<p<<endl;
// cout<<"q="<<q<<endl;
p=891234941;
q=1123984201;
ll e, m=(p-1)*(q-1), x, y;
ext_gcd(d, m, x, y); //x是d对模m的逆元,y是m对模d的逆元
e=(x%m+m)%m; //防止x<0或x>m作的修正
// cout<<"e="<<e<<endl; //e=823816093931522017 意味着
ll C=20190324;
//cout<<power(C,e,n) <<endl; //求X=C^e mod n并输出X(估计至少要运行100年)
cout<<fpm(C,e,n)<<endl; //求X=C^e mod n并输出X (快速幂算法)
return 0;
}
【完全二叉树的权值】
比赛时,多拟几组数据,确保编程正确!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
ll maxsum = -755360000011, sum; //最大和,每层整数和
int N, num, cnt=0;
int flag =0; //flag为 1表示已经读入了所有的整数
int layer,maxlayer=1;
int i;
cin>>N;
//读入每一层的结点,根结点为第一层
for(layer=1; ;layer++){
sum=0;
//读入每层layer的所有结点,2^(layer-1)
for(i=0;i<(1<<(layer-1));i++ ) //1按位左移计算,二进制左移
{
cin>>num;
sum+=num;
//已读入的整数个数已经到达了N个
if(++cnt>=N){
flag = 1; break;
}
}
//一层
if(sum>maxsum){
maxsum=sum;
maxlayer=layer;
}
if(flag) break;
}
cout<<maxlayer<<endl;
return 0;
}
【外卖店优先级】
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int MAXN=100010;
const int MAXM=100010;
int N,M,T;
int priority[MAXN];//priority记录外卖店优先级(初值为0)
int last[MAXN];//Last记录外卖店上一个订单的时刻(初值为0)
bool st[MAXN];//外卖店是否在优先缓存中的标志
PII order[MAXM];//每个订单的时刻(ts)及外卖店(id)
int main()
{
int i,j;
scanf("%d%d%d", &N, &M, &T);
for(i=0; i<M; i++)
scanf("%d%d", &order[i].first, &order[i].second);
sort(order,order + M);//按照订单时间先后排序,时间相同再按外卖店序号从小到大排序
for(i = 0; i<M;){//只考虑有订单的时刻(即M条订单)
j = i;
while(j< M && order[j]==order[i]) j++;//同一时间同一店铺有多条订单
int t = order[i].first,id = order[i].second, cnt = j-i;//订单数
i=j;
priority[id] -= t-last[id] - 1;//先减去没有订单的优先级
if(priority[id]<0) priority[id] =0;//优先级最低为0
if(priority[id]<=3) st[id] = false;//出缓存
priority[id] += cnt*2;//加上cnt个订单带来的优先级
if(priority[id] >5) st[id] = true;//进缓存
last[id] = t;//维护last
}
for(i = 1; i <= N; i++){//最后T时刻更新所有店铺优先级
if(last[i]<T){
priority[i]-=T-last[i];
if(priority[i]<=3) st[i]=false;
}
}
int ans = 0;//最终答案:在优先缓存中的外卖店数量
for(i = 1; i <=N; i++ ) ans+= st[i];
printf("%d\n",ans);
return 0;
}
【修改数组】
80%
#include<bits/stdc++.h>
#include<time.h>
using namespace std;
#define MAXN 100005
#define MAXA 100005
int A[MAXN];
int bused[MAXA];//1~100000o是否已经出现过的标志
int main( )
{
//freopen("d2.in","r", stdin);
// freopen("d2.out","w", stdout);
time_t time, start, end;//程序运行总时间、程序运行开始时刻、结束时刻
start = clock( );//取得系统当前时刻
int i,j,N;
scanf( "%d",&N);
for(i = 1; i<=N; i++)
scanf( "%d",&A[i]);
bused[A[1]]= 1;
for(i=2; i<=N; i++){//调整A[i]:检查A[1]~A[i-1]
if( !bused[A[i]]){ //A[i]没有出现过,直接在bused数组里将A[i]所处位置标志置1
bused[A[i]] = 1; continue;
}
do{//A[i]已经出现过,则A[i]增加1,再判断A[i]you|
A[i]++;
}while(bused[A[i]]);
bused[A[i]]= 1;
}
for(i = 1; i <N; i++)
printf("%d ",A[i]);
printf("%d\n",A[N]);
end = clock( );//取得系统当前时刻
time = end - start;
// printf("%d\n", time );
return 0;
}
100% 并长集 -高手入
【糖果】
【组合数问题】
【指路】蓝桥杯第 8-10 届真题解析 - 《组合数问题》名师讲解 - 蓝桥云课 (lanqiao.cn)