NOIP模拟题 [暴力][贪心][栈][dfs][找规律]
2016-11-01 14:55
323 查看
不擅长写暴力,要多练。
学习一下传说中的打表找规律。
定数组大小之前一定要认真地算并且留够变化区间(即如果算出来是1e5左右,你开1e5,你死了。(我就是这么死的摔,长记性啊。)
稳啊稳啊,每次都要交智商税吗。
T1:
题意:
对于给定序列进行加数(若有三个及以上相同则删除),输出每次加数后的序列。
分析:
按理说典型链表,不过看一下数据范围,感觉写链表多用的时间应该是智商税(看到这里的链表同学求不揍);
T2:
题意:
对于给定序列做进出栈操作,求通过操作能得到的字典序最大数列。
分析:字典序最大,马上想到贪心,然后每次就从能取的里面选最大(能取的:栈顶或未入栈)
T3:
题意:
给个序列,找规律。
分析:
据说可以打表找答案规律。
我不擅长写暴力所以没有打表,自己乱写乱画地找规律,居然还找到了,在这里对自己的乱写乱画能力表示佩服。
打表法:打表以后做等差,可以看到A[]序列的映射。
乱写乱画发现的规律也是一样的,不过可以证明:所求的last(last(i)),就是这种次数最后一次出现的地方,也就是对于初始式子进行相同系数合并以后,它出现的地方的位置值。
据说直接二分会更快。
学习一下传说中的打表找规律。
定数组大小之前一定要认真地算并且留够变化区间(即如果算出来是1e5左右,你开1e5,你死了。(我就是这么死的摔,长记性啊。)
稳啊稳啊,每次都要交智商税吗。
T1:
题意:
对于给定序列进行加数(若有三个及以上相同则删除),输出每次加数后的序列。
分析:
按理说典型链表,不过看一下数据范围,感觉写链表多用的时间应该是智商税(看到这里的链表同学求不揍);
#include<cstdio> #include<iostream> #include<cmath> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<set> #include<map> #include<stack> #include<vector> #include<ctime> #define ll long long #define inf 2e8 #define modd 1e9+7 #define clr(x) memset(x,0,sizeof(x)) #define maxen(x) memset(x,127,sizeof(x)) #define maxer(x) memset(x,31,sizeof(x)) #define each(i,n) for(int i=1;i<=n;i++) #define minn(a,b,c) min(a,min(b,c)) #define maxx(a,b,c) max(a,max(b,c)) #ifdef WIN32 #define lld "%I64d" #else #define lld "%lld" #endif #define PROC "hao" //for(int i=1;i<=n;i++) //(double) (ll) LL (int) //(double)clock()/CLOCKS_PER_SEC using namespace std; const int Maxn=3e3+5; int n,pos,len,ins,cnt,flg,lef,rig,num; char lac[Maxn]; int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } void init() { scanf("%s",lac); num=len=strlen(lac); n=read(); } int cler(int cur) { int lefnum=0,rignum=0; for(lef=cur+1;lef<len;lef++) if(lac[lef]!=' '&&lac[lef]!=lac[cur]) break; else if(lac[lef]!=' ')lefnum++; lef--; for(rig=cur-1;rig>=0;rig--) if(lac[rig]!=' '&&lac[rig]!=lac[cur]) break; else if(lac[rig]!=' ')rignum++; rig++; if(lefnum+rignum+1>=3){ for(int i=rig;i<=lef;i++) if(lac[i]!=' ') lac[i]=' ',num--; int flg3=0; for(lef;lef<len;lef++){ if(lac[lef]!=' '){flg3=1;break;} } if(!flg3){ for(rig;rig>=0;rig--) if(lac[rig]!=' '){flg3=1;break;} lef=rig; } if(!flg3)return 0; return 1; } return 0; } void work() { each(i,n){ pos=read(); ins=getchar(); cnt=0;len++;flg=0;num++; for(int j=len-1;j>=0;j--) if(flg){ lac[j]=ins; while(cler(j))cler(lef),j=lef; break; } else { lac[j]=lac[j-1]; if(lac[j]!=' ')cnt++; if(cnt==num-pos-1) flg=1; } flg=0; for(int j=0;j<len;j++) if(lac[j]!=' ') flg=1,printf("%c",lac[j]); if(!flg)printf("-"); printf("\n"); } } void debug() { // } int main() { freopen(PROC".in","r",stdin); freopen(PROC".out","w",stdout); init(); work(); //debug(); return 0; }
T2:
题意:
对于给定序列做进出栈操作,求通过操作能得到的字典序最大数列。
分析:字典序最大,马上想到贪心,然后每次就从能取的里面选最大(能取的:栈顶或未入栈)
#include<cstdio> #include<iostream> #include<cmath> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<set> #include<map> #include<stack> #include<vector> #include<ctime> #define ll long long #define inf 2e8 #define modd 1e9+7 #define clr(x) memset(x,0,sizeof(x)) #define maxen(x) memset(x,127,sizeof(x)) #define maxer(x) memset(x,31,sizeof(x)) #define each(i,n) for(int i=1;i<=n;i++) #define minn(a,b,c) min(a,min(b,c)) #define maxx(a,b,c) max(a,max(b,c)) #ifdef WIN32 #define lld "%I64d" #else #define lld "%lld" #endif #define PROC "kun" //for(int i=1;i<=n;i++) //(double) (ll) LL (int) //(double)clock()/CLOCKS_PER_SEC using namespace std; const int Maxn=1e6+5; int n,cnt,tail,a[Maxn],b[Maxn],sta[Maxn]; bool instack[Maxn]; int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } void init() { n=read(); for(int i=1;i<=n;i++){ a[i]=read(); b[a[i]]=i; } cnt=1; } void work() { for(int i=n;i>=1;i--) if((!instack[i])||sta[tail]==i){ printf("%d ",i); if(instack[i])instack[i]=false,tail--; while(sta[tail]>i)printf("%d ",sta[tail--]); for(int j=cnt;j<b[i];j++) sta[++tail]=a[j],instack[a[j]]=true; cnt=max(cnt,b[i]+1); } while(tail)printf("%d ",sta[tail--]); } void debug() { // } int main() { freopen(PROC".in","r",stdin); freopen(PROC".out","w",stdout); init(); work(); //debug(); return 0; }
T3:
题意:
给个序列,找规律。
分析:
据说可以打表找答案规律。
我不擅长写暴力所以没有打表,自己乱写乱画地找规律,居然还找到了,在这里对自己的乱写乱画能力表示佩服。
打表法:打表以后做等差,可以看到A[]序列的映射。
乱写乱画发现的规律也是一样的,不过可以证明:所求的last(last(i)),就是这种次数最后一次出现的地方,也就是对于初始式子进行相同系数合并以后,它出现的地方的位置值。
据说直接二分会更快。
#include<cstdio> #include<iostream> #include<cmath> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<set> #include<map> #include<stack> #include<vector> #include<ctime> #define ll long long #define inf 2e8 #define clr(x) memset(x,0,sizeof(x)) #define maxen(x) memset(x,127,sizeof(x)) #define maxer(x) memset(x,31,sizeof(x)) #define each(i,n) for(int i=1;i<=n;i++) #define minn(a,b,c) min(a,min(b,c)) #define maxx(a,b,c) max(a,max(b,c)) #ifdef WIN32 #define lld "%I64d" #else #define lld "%lld" #endif #define PROC "nan" //for(int i=1;i<=n;i++) //(double) (ll) LL (int) //(double)clock()/CLOCKS_PER_SEC using namespace std; const int Maxn=2e3+5; const long long modd=1e9+7; int t,cur,cnt,lll; long long ans[Maxn],roa[Maxn*100]; struct node { long long val; int num; }a[Maxn]; bool cmp1(node x,node y) { return x.val<y.val; } bool cmp2(node x,node y) { return x.num<y.num; } int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } void init() { t=read(); for(int i=1;i<=t;i++){ a[i].val=(long long)read(); a[i].num=i; } sort(a+1,a+t+1,cmp1); cur=1; cnt=2; lll=4; roa[1]=1; roa[2]=2; roa[3]=2; } const long long limi=1e5; void dfs(ll val,ll pos,ll tii,ll tim) { for(int i=cur;i<=t;i++) if(a[i].val<pos+tii){ ans[a[i].num]=(val+(a[i].val+pos)*(a[i].val-pos+1LL)/2LL*tim)%modd; cur++; } else break; if(cur==t+1)return; for(lll;lll<min(limi,tii+pos);lll++) roa[lll]=tim; dfs((val+(2LL*pos+tii-1LL)*tii/2LL*tim)%modd, tii+pos,roa[++cnt],tim+1); } void work() { dfs(1LL,2LL,2LL,2LL); for(int i=1;i<=t;i++) printf("%I64d\n",ans[i]); } void debug() { // } int main() { freopen(PROC".in","r",stdin); freopen(PROC".out","w",stdout); init(); work(); //debug(); return 0; }
相关文章推荐
- [NOIP模拟题][Catalan数][逆元][贪心][线段树][DFS][搜索顺序剪枝]
- NOIP模拟题 [构造][贪心][暴力]
- 【NOIP模拟题】【hash表】【暴力求解】2016.11.16 第三题 LGTB 与正方形 题解
- 【NOIP模拟题】Graph(tarjan+dfs)
- 2017蓝桥杯模拟题 滑动解锁(暴力DFS)
- 2015多校第6场 HDU 5355 Cake 贪心,暴力DFS
- 【DFS序】【线段树】【选派士兵】【noip模拟题】
- 数学 | 推理 | 思维 | 打表 | 找规律 | 贪心 | 暴力
- NOIP模拟题[贪心][离散化][LIS]
- [CF750D] New Year and Fireworks(暴力,规律,dfs)
- 2017蓝桥杯模拟题 滑动解锁(暴力DFS)
- NOIP模拟题 kun 栈 贪心 解题报告
- 2017蓝桥杯模拟题 滑动解锁(暴力DFS)
- 湖南NOIP集训模拟题DAY1 BY ExfJOE [贪心][DP][二分]
- 【贪心】NOIP模拟题“Kun”
- 【NOIP 模拟题】中位数(规律+递推)
- [NOIP模拟题][杂题][状压DP][DFS序][线段树]
- NOIP模拟题 2017.7.3 - 模拟 - 贪心 - 记忆化搜索
- 2017蓝桥杯模拟题 滑动解锁(暴力DFS)
- NOIP模拟题 2016.11.10 [模拟] [状压DP] [线段树] [DFS序]