一些奇思妙想的模拟题
来源:互联网 发布:网络协议的四层模型 编辑:程序博客网 时间:2024/04/28 07:51
HDU1005
A number sequence is defined as follows:
f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.
Given A, B, and n, you are to calculate the value of f(n).
分析:
开始的时候想,计算的过程中直接mod7可以防止溢出,后来发现爆内存,因为数很小,是有规律的,如果连续的两个数都和前面连续的两个数都相同了,那么后面的数一定也相同,构成循环。
因此最重要的是要找出循环节。
int rec[60];int main(){ int a, b, n; rec[0] = rec[1] = rec[2] = 1; while( scanf( "%d %d %d", &a, &b, &n ), a | b | n ){ int beg, end, flag = 0; for( int i = 3; i <= n && !flag; ++i ){ rec[i] = ( a * rec[i-1] + b * rec[i-2] ) % 7; for( int j = 2; j <= i - 1; ++j ){ if( rec[i] == rec[j] && rec[i-1] == rec[j-1] ){ beg = j, end = i; flag = 1; break; } } } if( flag ){ printf( "%d\n", rec[beg+(n-end)%(end-beg)] ); } else printf( "%d\n", rec[n] ); } return 0;}
HDU1014
题意:
seed(x+1) = [seed(x) + STEP] % MOD
seed(1)=0;
给定STEP和MOD判断是否能产生布满0-(MOD-1)区间的所有值
如果STEP和MOD在这个区间内部有大于1的公约数,那么就不可能产生布满整个区间的数,实际上,如果公约数是x那么,最后相邻两个数的值就是x
10,15最后只能有0,5,
bool f(int x,int y){ int m=x%y; if(m==0)return false; for(int i=2;i<=m;i++) { if(x%i==0&&y%i==0) return false; } return true;}
HDU1061
求N*N的最后一个数字是什么,
对于每一个阿拉伯数字0-9,求n次方都会有周期。
POJ1006
These three cycles are the physical, emotional, and intellectual cycles, and they have periods of lengths 23, 28, and 33 days,
给定三个高峰发生的时期,和一个给定的天d,计算下一个高峰距离这个d有多少天?
int a,b,c,d; int cnt=0; while(cin>>a>>b>>c>>d){ if(a==-1&&b==-1&&c==-1&&d==-1){ break; } cnt++; while(b>d){ b=b-28; } while(a>d){ a=a-23; } while(c>d){ c=c-33; } int res; for(int i=1;;i++){ if(((23*i+a-b)%28==0)&&((23*i+a-c)%33==0)){ if(23*i+a>d){ res=23*i+a;break;} } }
POJ3684,POJ1852
1,模拟自由落体的小球碰撞
2,模拟蚂蚁碰撞后原路返回
关键点在于:可以忽略一切碰撞,直接按照没有发生碰撞处理。
POJ1166
给定一些钟表,ABCDEFGHI,每个钟表有0,1,2,3代表时间,移动一个数字可以改变对应的钟表
1 ABDE 2 ABC 3 BCEF 4 ADG 5 BDEFH 6 CFI 7 DEGH 8 GHI 9 EFHI
判断为了让钟表还原成0需要的最少的步数。
4^9可以枚举
for(int i=1;i<=9;i++){scanf("%d",a+i);} for(b[1]=0;b[1]<=3;b[1]++) for(b[2]=0;b[2]<=3;b[2]++) for(b[3]=0;b[3]<=3;b[3]++) for(b[4]=0;b[4]<=3;b[4]++) for(b[5]=0;b[5]<=3;b[5]++) for(b[6]=0;b[6]<=3;b[6]++) for(b[7]=0;b[7]<=3;b[7]++) for(b[8]=0;b[8]<=3;b[8]++) for(b[9]=0;b[9]<=3;b[9]++) { c[1]=(a[1]+b[1]+b[2]+b[4])%4; c[2]=(a[2]+b[1]+b[2]+b[3]+b[5])%4; c[3]=(a[3]+b[2]+b[3]+b[6])%4; c[4]=(a[4]+b[1]+b[4]+b[5]+b[7])%4; c[5]=(a[5]+b[1]+b[3]+b[5]+b[7]+b[9])%4; c[6]=(a[6]+b[3]+b[5]+b[6]+b[9])%4; c[7]=(a[7]+b[4]+b[7]+b[8])%4; c[8]=(a[8]+b[5]+b[7]+b[8]+b[9])%4; c[9]=(a[9]+b[6]+b[8]+b[9])%4; if(c[1]+c[2]+c[3]+c[4]+c[5]+c[6]+c[7]+c[8]+c[9]==0){ int i=-1; for(i=0;i<b[1];i++) printf("1 "); for(i=0;i<b[2];i++) printf("2 "); for(i=0;i<b[3];i++) printf("3 "); for(i=0;i<b[4];i++) printf("4 "); for(i=0;i<b[5];i++) printf("5 "); for(i=0;i<b[6];i++) printf("6 "); for(i=0;i<b[7];i++) printf("7 "); for(i=0;i<b[8];i++) printf("8 "); for(i=0;i<b[9];i++) printf("9 "); printf("\n"); } }
POJ1013
称量乒乓球
一些乒乓球有一个质量不合格,或者是大或者是小,
给定左边和右边乒乓球的关系,左边重还是右边重,还是相等。找出这个球,是轻了,还是重了。
一开始想到的方法,是假设是重的球或者是轻的球,但是后来发现,需要进行两次模拟,比较繁琐。于是采用了如下巧妙的思路:
初始值设置为0
如果是左边的重了,将左边的每个球的偏移量+1,右边的每个球偏移量-1,如果是相等的,那么就不考虑。
最后统计偏移量绝对值最大的那个,根据正负,判断是重了,还是轻了。
for(int i=1;i<=12;i++){ zero[i]=t[i]=0;}for(int now=1;now<=3;now++){ cin>>l>>r>>d; if(d=="even"){ for(int i=0;i<l.size();i++){zero[l[i]-64]=1;}//标记为真说明,以后不用考虑了,因为一定是真的 for(int i=0;i<r.size();i++){zero[r[i]-64]=1;} } if(d=="up"){ for(int i=0;i<l.size();i++){t[l[i]-64]++;} for(int i=0;i<r.size();i++){t[r[i]-64]--;} } if(d=="down"){ for(int i=0;i<l.size();i++){t[l[i]-64]--;} for(int i=0;i<r.size();i++){t[r[i]-64]++;} }}int max=-1;int index=-1;for(int i=1;i<=12;i++){ if(zero[i]==0&&fabs(t[i])>max){ index=i; max=fabs(t[i]); }}if(t[index]>0)printf("%c is the counterfeit coin and it is heavy.\n",index+64);else printf("%c is the counterfeit coin and it is light.\n",index+64);
POJ2586
题意:不太好理解。有一个公司由于某个病毒使公司赢亏数据丢失,但该公司每月的赢亏是一个定数,要么一个月赢利s,要么一月亏d。现在ACM只知道该公司每五个月有一个赢亏报表,而且每次报表赢利情况都为亏。在一年中这样的报表总共有8次(1到5,2到6,…,8到12),现在要编一个程序确定当赢s和亏d给出,并满足每张报表为亏的情况下,全年公司最高可赢利多少,若存在,则输出多多额,若不存在,输出”Deficit”。
算法:枚举。既然盈亏是定数,可以想到可能出现的情况就那么几种,进而想到枚举。
x=1: ssssd,ssssd,ss d>4s 赢利10个月 10s-2d x=2: sssdd,sssdd,ss 2d>3s 赢利8个月 8s-4d x=3: ssddd,ssddd,ss 3d>2s 赢利6个月 6s-6d x=4: sdddd,sdddd,sd 4d>s 赢利3个月 3s-9d x=5: ddddd,ddddd,dd 4d<s 无赢利
#include <iostream>using namespace std;int main(){ int s, d; int sNum, dNum; while (scanf("%d%d", &s, &d) != EOF) { if (d > 4*s) { sNum = 10; dNum = 2; } else if (2*d > 3*s) { sNum = 8; dNum = 4; } else if (3*d > 2*s) { sNum = 6; dNum = 6; } else if (4*d > s) { sNum = 3; dNum = 9; } else { sNum = 0; dNum = 12; } int sum = sNum*s - dNum*d; (sum>0)? cout << sum << endl : cout << "Deficit"<<endl; }}
POJ2393
题意:任务规定,一个酸奶制造厂,在n个星期内,分别要向外提供y[i]unit的酸奶。已知这个制造厂第i周制造每unit酸奶的费用为c[i],储存室储存每1unit酸奶1星期的费用为s。问要完成这个任务的最小费用是多少。
看似是动态规划,实际上贪心处理一遍原数组即可。
对于每一天,考虑是当天生产的代价高,还是使用昨天生产的代价+储存代价高,选择一个代价低的,更新为当天的代价。
这样考虑实际上是考虑了相隔很远的情况。
假如第一天的代价是1,最后一天的代价是INF,处理以后,最后一天的代价也会变得很小。这样处理之后原代价并不会发生变化
储存代价是5
第一天89 400
第二天97 300
第二天会被更新为->94
因此这样算的代价是89*400+(5+89)*300`
(89)*700+(5)*300`生产700,存放300
代表的意思就是
long long ans=0; for(int i=1;i<n;i++) c[i]=min(c[i-1]+s,c[i]); for(int i=0;i<n;i++) ans+=c[i]*y[i]; printf("%lld\n",ans);
- 一些奇思妙想的模拟题
- 收集的一些硬件,奇思妙想一
- 收集的一些硬件,奇思妙想二
- 各种奇思妙想的怪异网站
- 爱T派的奇思妙想
- 异地恋的奇思妙想
- 【Python】关于Python的奇思妙想
- 奇思妙想废话连篇
- 奇思妙想(一)
- 链表-奇思妙想
- 奇思妙想<二>
- 奇思妙想
- 奇思妙想
- CSS 奇思妙想
- 不仅仅是奇思妙想
- 奇思妙想之开篇
- 奇思妙想位运算
- 有意思的数字游戏,真是奇思妙想!
- Python 如何安装各种模块(1)
- Java并发容器(一) CocurrentHashMap的应用及实现
- Java入门 第一季第四章 流程控制语句
- Nginx探索二
- STM32f103 外部引中断
- 一些奇思妙想的模拟题
- BFS--广度优先搜索--图的邻接表
- setsockopt
- java写JSON格式化的方法
- 2440裸机lEd
- Java的多态
- 递归
- NameNode中数据节点的保存(1)——Host2NodesMap
- 关于chrome的字体怎么设置小于12px的问题