这一套题真是做了一晚上只对了仨填空- - 其中一个还是靠记得小学数学一道题 蒙上的答案 还对了。。。
要是蓝桥还这个难度我就完辽。。。自己真的太菜辽。。。
qxgg说 不要轻视蓝桥 它简单的题贼简单 难的题贼难 而且是oi赛制 所以如果遇到大题不会了 也要输出样例骗分!
因为蓝桥和ACM不一样 不能得到自己代码的实时反馈结果 所以一定要求稳!各种小错误一有就完了!!!
没什么说的直接暴力判断
const int maxn=1e5+10;
int prime[maxn];
bool con[maxn];
inline bool judge(int num){
while(num){
if(num%10==5) return true;
num/=10;
}
return false;
}
int main() {
rep(i,2,maxn-1){
if(con[i]) continue;
rep(j,2,maxn){
if(i*j>=maxn) break;
con[i*j]=true;
}
}
int k=0;
rep(i,2,maxn-1){
if(!con[i]) prime[++k]=i;
}
int cnt=0;
rep(i,1,k){
if(prime[i]>100000) break;
if(judge(prime[i])) cnt++;
}
printf("%d\n",cnt);
return 0;
}
一共才十层 搜索一下就好
int dfs(int d){
if(d==1) return 1;
if(d==2) return 2;
if(d==3) return 1+dfs(2)+dfs(1);
if(d==4) return 1+dfs(3)+dfs(2)+dfs(1);
if(d==5) return 0;
if(d==7) return 0;
return dfs(d-1)+dfs(d-2)+dfs(d-3)+dfs(d-4);
}
int main() {
printf("%d\n",dfs(10));
system("pause");
return 0;
}
这个我是想起小学的切饼问题。。。
总之每一条直线(每一刀
都切中尽可能多的块就行
第一次发现可以切6块 所以会多六块 然后后面每次切就多一块
所以答案=7+6+7+8+9+10=47
没想到竟然对了。。。没写代码。。。直接这么想的
自己不会。。题解说从左往右 先拿一堆三个的 再拿三堆 一堆一个的拿
小贪心吧
下面是代码
//从两个方向贪心 优先一堆拿三个 不够了再从右边
int a[33],b[33];
int main() {
rep(i,1,30){
sd(a[i]);
b[30+1-i]=a[i];
}
int cnt=0,cnt2=0;
for(int i=1;i<=30;i++){
cnt+=a[i]/3;
a[i]%=3;
while(a[i]>=1&&a[i+1]>=1&&a[i+2]>=1){
a[i]--,a[i+1]--,a[i+2]--;
cnt++;
}
cnt2+=b[i]/3;
b[i]%=3;
while(b[i]>=1&&b[i+1]>=1&&b[i+2]>=1){
b[i]--,b[i+1]--,b[i+2]--;
cnt2++;
}
}
rep(i,1,30) printf("%d ",a[i]);putchar('\n');
rep(i,1,30) printf("%d ",b[i]);putchar('\n');
printf("%d %d\n",cnt,cnt2);
printf("%d\n",max(cnt,cnt2));
return 0;
}
和欧拉函数有点关系 会补的 算了就这样吧 太难了太难了
题解用了unordered_map 不会用啊莫名其妙的 会补的 补是不可能的
写到吐的大模拟
昨天晚上没过 今天早晨起来一搜题解说 题面错了
应该统计三种各自有多少被降低为0 而不是各自受的伤害
然后改了之后还是不对
发现自己计算溅射伤害方法有问题 因为遇到边界 某一点受到的溅射伤害可能不是3 5 8 而且还要分析k*k 之外收到的溅射伤害- -这里忘了
然后改了之后发现还是不对
发现最后总数可能爆int 最后改了long long 就对了- -
const int maxn=310;
ll blood[4];//三种血量
ll sum[4];//三种受的伤
int mp[maxn][maxn];//编号地图
ll now[maxn][maxn];//血量地图
ll hurt[maxn][maxn];//基本伤害
ll jian[maxn][maxn];//溅射伤害 事实证明用不到- -
int dir[8][2]={1,0,1,1,0,1,-1,1,-1,0,-1,-1,0,-1,1,-1};
int main() {
int n,m;
sdd(n,m);
scanf("%lld%lld%lld",&blood[1],&blood[2],&blood[3]);
int k;
ll w;//范围与溅射伤害
scanf("%d%lld",&k,&w);
rep(i,1,k){
rep(j,1,k){
scanf("%lld",&hurt[i][j]);
}
}
rep(i,1,n)
rep(j,1,m){
sd(mp[i][j]);
now[i][j]=blood[mp[i][j]];
}
//计算攻击
int q;
sd(q);
while(q--){
int op,x,y;
sd(op);sdd(x,y);//爆炸中心x y
//先基本伤害 默认k是奇数
int s1,s2,t1,t2;//行列开始 行列结束
s1=max(1,x-k/2);
t1=min(n,x+k/2);
s2=max(1,y-k/2);
t2=min(m,y+k/2);
rep(i,s1,t1){
rep(j,s2,t2){
//ii jj是对应炸弹范围的坐标
//1 1
int ii=i-(x-k/2-1);
int jj=j-(y-k/2-1);
if(now[i][j]>0){//若当前土地还有
sum[mp[i][j]]+=min(now[i][j],hurt[ii][jj]);
now[i][j]-=hurt[ii][jj];
}
if(op==0){//若有溅射伤害
//得分情况算
for(int dd=0;dd<8;dd++){//地图上的八个方向
int i1=i+dir[dd][0];
int j1=j+dir[dd][1];
if(i1<1||i1>n||j1<1||j1>m) continue;
if(now[i1][j1]>0){
sum[mp[i1][j1]]+=min(now[i1][j1],w);
now[i1][j1]-=w;
}
}
}
}
}
}
int cnt[4]={0,0,0,0};
rep(i,1,n)
rep(j,1,m)
if(now[i][j]<=0) cnt[mp[i][j]]++;
//sum有可能超限!!!
printf("%d %d %d\n%lld\n",cnt[1],cnt[2],cnt[3],sum[1]+sum[2]+sum[3]);
//system("pause");
return 0;
}
26进制转换 大数模拟balabla 自己大数计算从来不好 会补的 补是不可能的- -
题面有点问题 应该是n-1个顾客
之前做过这种类型的 因为求的是1到其他各点 和其他各点到1这个点的最短路
所以只用单源最短路即可 第二次反向建边 求和所有的dis即可
要注意!dis要初始化为1e18以上 !!自己刚开始不到这个 过的组数只有五组- -
下面是ac代码 (dijkstra+堆优化
const int maxn=2e4+10;
const int maxm=6e4+10;
int n,m,cnt;
ll ans;
struct Side0{
int u,v;
ll val;
}side0[maxm];
struct Side{
int v,next;
ll val;
}side[maxm];
int head[maxn],con[maxn];
ll dis[maxn];
struct node{
int id;
ll dis;
bool operator<(const node &oth)const{
return dis>oth.dis;
}
};
void add(int u,int v,ll val){
side[cnt].v=v;
side[cnt].val=val;
side[cnt].next=head[u];
head[u]=cnt++;
}
void dijkstra(){
priority_queue<node> q;
while(!q.empty()) q.pop();
rep(i,1,n) {//服了!!!就是这里!!!
dis[i]=0x3f3f3f3f3f3f3f3f;//inf不够大!!!
con[i]=0;
}
dis[1]=0;
node tp;
tp.id=1;
tp.dis=0;
q.push(tp);
while(!q.empty()){
int u=q.top().id;
if(con[u]){
q.pop();
continue;
}
con[u]=1;
for(int i=head[u];i!=-1;i=side[i].next){
int v=side[i].v,val=side[i].val;
if(dis[v]>dis[u]+val){
dis[v]=dis[u]+val;
tp.id=v,tp.dis=dis[v];
q.push(tp);
}
}
}
rep(i,2,n) ans+=dis[i];
}
void fun1(){//正向建边求路
cnt=0;
rep(i,1,n) head[i]=-1;
rep(i,1,m)
add(side0[i].u,side0[i].v,side0[i].val);
dijkstra();
}
void fun2(){//反向建边
cnt=0;
rep(i,1,n) head[i]=-1;
rep(i,1,m){
add(side0[i].v,side0[i].u,side0[i].val);
}
dijkstra();
}
int main() {
int T;
sd(T);
while(T--){
sdd(n,m);
ans=0;
rep(i,1,m){
sdd(side0[i].u,side0[i].v);
scanf("%lld",&side0[i].val);
}
fun2();
fun1();
printf("%lld\n",ans);
}
return 0;
}
这个题要注意以下几点:
1、bfs很容易确定 因为是最少多少花费
2、对于当前的某个点 我们操作步骤是:1、该点是否为终点 2、该点是不是传送门起点 3、该点周围四个点能否到达
为什么要先判断是否为传送门起点而不是四周的点呢?
因为传送门花费为0 四周的点花费为1
const int maxn=1010;
int n,m,num,x,y;//传送门个数
char mp[maxn][maxn];//地图
bool con[maxn][maxn];//这个点有没有来过
int nextt[4][2]{1,0,0,1,-1,0,0,-1};
struct tran{
int a,b,c,d;
}door[110];
struct node{
int x,y,dep;//所花费时间
bool operator<(const node &oth)const{
return dep>oth.dep;
}
};
bool inline judge(int x,int y){
if(x<1||x>n||y<1||y>m||con[x][y]||mp[x][y]=='*') return false;
return true;
}
int bfs(){
queue<node> q;
while(!q.empty()) q.pop();
node tp;
tp.x=tp.y=1;
tp.dep=0;
q.push(tp);
con[1][1]=true;
while(!q.empty()){
//printf("%d %d %d\n",q.top().x,q.top().y,q.top().dep);
tp=q.front();
q.pop();
bool flag=false;//先!!判断是否为传送门 是传送门的话 无法往周围走
rep(i,1,m){//哈哈哈哈哈AC了哈哈哈哈哈哈!就是这个flag判断!!!
if(tp.x==door[i].a&&tp.y==door[i].b){
flag=true;
if(!judge(door[i].c,door[i].d)) break;
node tp1;
tp1.x=door[i].c;
tp1.y=door[i].d;
tp1.dep=tp.dep;
q.push(tp1);
break;
}
}
if(flag) continue;
for(int i=0;i<4;i++){//除了四个方向外 还要有传送门的方向
node tp1;
tp1.x=tp.x+nextt[i][0];
tp1.y=tp.y+nextt[i][1];
tp1.dep=tp.dep+1;
if(!judge(tp1.x,tp1.y)) continue;
if(tp1.x==x&&tp1.y==y) return tp1.dep;
q.push(tp1);
con[tp1.x][tp1.y]=true;
}
}
return -1;
}
int main() {
sdd(n,m);getchar();
rep(i,1,n){
rep(j,1,m){
con[i][j]=false;
mp[i][j]=getchar();
}getchar();
}
sd(num);
rep(i,1,num){
sdd(door[i].a,door[i].b);
sdd(door[i].c,door[i].d);
}
sdd(x,y);
int ans=bfs();
if(ans==-1) printf("No solution\n");
else printf("%d\n",ans);
//system("pause");
return 0;
}