NOIP模拟题 [构造][贪心][暴力]
2016-11-08 17:04
387 查看
从以往犯的错上汲取经验。
注意循环,if的嵌套以及break等地方。
训练暴力能力。
如果要修改一个地方一定注意看一下有没有忘了的东西!还有复制黏贴也是一样。
T1:
题意:
给定一些字符串,可对字符串的长度为偶数的前缀进行反转操作,相同则消除,求最后剩下多少。
分析:
先考虑把后面的匹配,则只要把某两个看作一块,只要还有一个相同且没有被配对的块,就一定可以被翻到最前面且调换方向,然后翻到最后。
没有break导致多次配对,以后一定要有满足就返回的思想。
T2:
题意:
给定一些怪物的参数,要求选出一怪物和与之战斗的怪物,使得最后这一怪物的能量+能力值最大。
对战斗定义如下:
只有能力严格更大才能赢,赢后能力加上战败者能量,减去战败者能力。
分析:
把怪物分为能力大和能力小于等于,然后去取两类的最优比较即可。
最优定义:
能力小于等于:能力排序。
证明:先不考虑自身能力能量和打败对方,则能力更大的可能获取到的至少不会更小。
然后考虑自身能力,考虑能力小的怪物能打败能力大的怪物的情况,另一情况显然更满足。
令a2<b2,a1< b1,a2>a1;(a:能力,b能量,下同)
则能力大的怪物此模块的值:a2+b2+b1-a1;
小的:a1+b1+b2-a2;
作差得:2a2-2a1>0;
得证。
能力大:能力+能量排序。
证明:
令a1+b1>a2+b2;
a1< a3< a2;
b3>a3;
人话来说就是考虑有一个排序更高的不能杀死一个排序低的能杀死且收益为正的怪物。
a3+b3>a1+b1+b3-a3;
若a2杀死a3,收益:
a2+b2+b3-a3;
若a3不死,自身:
a3+b3;
所以对于能力大的怪物,要么就直接不杀,如果要杀,则被杀的那个不被杀反而是最优,所以只用考虑不杀的情况,得证。
T3:
题意:
模拟文件处理系统,支持文件夹,文件的进入创建删除列表,支持进入父目录。
分析:
就一暴力,双向存树,儿子节点用邻接链表,一个数组表示是否被删(因为直接在链表上删不方便),按照时间顺序列表的时候就递归打印。
如果要修改一个地方一定注意看一下有没有忘了的东西!还有复制黏贴也是一样。
注意循环,if的嵌套以及break等地方。
训练暴力能力。
如果要修改一个地方一定注意看一下有没有忘了的东西!还有复制黏贴也是一样。
T1:
题意:
给定一些字符串,可对字符串的长度为偶数的前缀进行反转操作,相同则消除,求最后剩下多少。
分析:
先考虑把后面的匹配,则只要把某两个看作一块,只要还有一个相同且没有被配对的块,就一定可以被翻到最前面且调换方向,然后翻到最后。
没有break导致多次配对,以后一定要有满足就返回的思想。
#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 minus(x) memset(x,-1,sizeof(x)) #define each(i,n,m) for(int i=n;i<m;i++) #define eachrev(i,n,m) for(int i=n;i>m;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 "kahuucino" //for(int i=1;i<=n;i++) //(double) (ll) LL (int) //(double)clock()/CLOCKS_PER_SEC using namespace std; const int Maxn=55; int ans,t,n,len[Maxn],used[Maxn],bj[Maxn]; char a[Maxn][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(); each(i,1,n+1){ cin.getline(a[i],Maxn); len[i]=strlen(a[i]); } ans=0;clr(used); } void work() { each(i,1,n+1) if(!used[i]) each(j,1,n+1) if(!used[j]&&i!=j){ if(len[i]!=len[j])continue; if(len[i]%2&&a[i][len[i]-1]!=a[j][len[i]-1])continue; clr(bj); for(int k=0;k<len[i];k+=2){ for(int z=0;z<len[i];z+=2) if((!bj[z])&&a[i][k]==a[j][z]&&a[i][k+1]==a[j][z+1]){ bj[z]=1;break;} else if((!bj[z])&&a[i][k]==a[j][z+1]&&a[i][k+1]==a[j][z]){ bj[z]=1;break;} } int flg=0; for(int z=0;z<len[i];z+=2) if(!bj[z]){ flg=1;break; } if(!flg){ used[i]=used[j]=1; break; } } for(int i=1;i<=n;i++) if(!used[i])ans++; printf("%d\n",ans); } void debug() { // } int main() { freopen(PROC".in","r",stdin); freopen(PROC".out","w",stdout); t=read(); each(i,0,t){ init(); work(); } //debug(); return 0; }
T2:
题意:
给定一些怪物的参数,要求选出一怪物和与之战斗的怪物,使得最后这一怪物的能量+能力值最大。
对战斗定义如下:
只有能力严格更大才能赢,赢后能力加上战败者能量,减去战败者能力。
分析:
把怪物分为能力大和能力小于等于,然后去取两类的最优比较即可。
最优定义:
能力小于等于:能力排序。
证明:先不考虑自身能力能量和打败对方,则能力更大的可能获取到的至少不会更小。
然后考虑自身能力,考虑能力小的怪物能打败能力大的怪物的情况,另一情况显然更满足。
令a2<b2,a1< b1,a2>a1;(a:能力,b能量,下同)
则能力大的怪物此模块的值:a2+b2+b1-a1;
小的:a1+b1+b2-a2;
作差得:2a2-2a1>0;
得证。
能力大:能力+能量排序。
证明:
令a1+b1>a2+b2;
a1< a3< a2;
b3>a3;
人话来说就是考虑有一个排序更高的不能杀死一个排序低的能杀死且收益为正的怪物。
a3+b3>a1+b1+b3-a3;
若a2杀死a3,收益:
a2+b2+b3-a3;
若a3不死,自身:
a3+b3;
所以对于能力大的怪物,要么就直接不杀,如果要杀,则被杀的那个不被杀反而是最优,所以只用考虑不杀的情况,得证。
#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 minus(x) memset(x,-1,sizeof(x)) #define each(i,n,m) for(int i=n;i<m;i++) #define eachrev(i,n,m) for(int i=n;i>m;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 "zyougamaya" //for(int i=1;i<=n;i++) //(double) (ll) LL (int) //(double)clock()/CLOCKS_PER_SEC using namespace std; const int Maxn=1e5+5; struct node { long long figh,ener; int num; }kuri[Maxn]; int bigg[Maxn],smal[Maxn]; int bigghead,smalhead; long long n,biggtot,smaltot,figh,ener,fighbigg,fighsmal,enerbigg,enersmal; long long 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; } bool cmp1(int x,int y) { return kuri[x].figh+kuri[x].ener>kuri[y].figh+kuri[y].ener; } bool cmp2(int x,int y) { if(kuri[x].figh!=kuri[y].figh)return kuri[x].figh>kuri[y].figh; return kuri[x].ener>kuri[y].ener; } bool cmp3(node x,node y) { return x.figh<y.figh; } void init() { n=read(); each(i,1,n+1){ kuri[i].figh=read(); kuri[i].ener=read(); kuri[i].num=i; if(kuri[i].figh>kuri[i].ener) bigg[++bigghead]=i; else smal[++smalhead]=i; } sort(bigg+1,bigg+bigghead+1,cmp1); fighbigg=kuri[bigg[1]].figh; enerbigg=kuri[bigg[1]].ener; sort(smal+1,smal+smalhead+1,cmp2); fighsmal=kuri[smal[1]].figh; enersmal=kuri[smal[1]].ener; sort(kuri+1,kuri+n+1,cmp3); } void work() { if(bigghead){ figh=fighbigg; ener=enerbigg; for(int i=1;i<=n;i++){ if(figh<=kuri[i].figh)break; if(kuri[i].num==bigg[1])continue; if(kuri[i].figh>=kuri[i].ener)continue; figh+=kuri[i].ener-kuri[i].figh; } biggtot=figh+ener; } if(smalhead){ figh=fighsmal; ener=enersmal; for(int i=1;i<=n;i++){ if(figh<=kuri[i].figh)break; if(kuri[i].num==smal[1])continue; if(kuri[i].figh>=kuri[i].ener)continue; figh+=kuri[i].ener-kuri[i].figh; } smaltot=figh+ener; } printf("%I64d",max(biggtot,smaltot)); } void work2() { for(int i=1;i<=n;i++){ figh=kuri[i].figh; ener=kuri[i].ener; for(int j=1;j<=n;j++){ if(figh<=kuri[j].figh)break; if(i==j)continue; if(kuri[j].figh>=kuri[j].ener)continue; figh+=kuri[j].ener-kuri[j].figh; } biggtot=max(biggtot,figh+ener); } printf("%I64d",max(biggtot,smaltot)); } void debug() { // } int main() { freopen(PROC".in","r",stdin); freopen(PROC".out","w",stdout); init(); if(n>=1000)work(); else work2(); //debug(); return 0; }
T3:
题意:
模拟文件处理系统,支持文件夹,文件的进入创建删除列表,支持进入父目录。
分析:
就一暴力,双向存树,儿子节点用邻接链表,一个数组表示是否被删(因为直接在链表上删不方便),按照时间顺序列表的时候就递归打印。
如果要修改一个地方一定注意看一下有没有忘了的东西!还有复制黏贴也是一样。
#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 minus(x) memset(x,-1,sizeof(x)) #define each(i,n,m) for(int i=n;i<m;i++) #define eachrev(i,n,m) for(int i=n;i>m;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 "nacumegu" //for(int i=1;i<=n;i++) //(double) (ll) LL (int) //(double)clock()/CLOCKS_PER_SEC const int Maxn=105; int n,len,cur=1,cnt=1; int typ[Maxn],exi[Maxn],fa[Maxn],fr[Maxn],tov[Maxn]; using namespace std; string opt,name[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(); exi[cur]=typ[cur]=1; } void cdD() { string a=""; for(int i=3;i<len;i++) a+=opt[i]; for(int i=fr[cur];i;i=tov[i]) if(exi[i]&&typ[i]&&name[i]==a){ cur=i;return; } printf("No such directory!\n"); } void cdf() { if(fa[cur]){ cur=fa[cur];return; } printf("No parent directory!\n"); } void tou() { string a=""; for(int i=6;i<len;i++) a+=opt[i]; for(int i=fr[cur];i;i=tov[i]) if(exi[i]&&typ[i]==0&&name[i]==a){ printf("File already exists!\n"); return; } tov[++cnt]=fr[cur]; fr[cur]=cnt; exi[cnt]=1; name[cnt]=a; fa[cnt]=cur; } void rmf() { string a=""; for(int i=3;i<len;i++) a+=opt[i]; for(int i=fr[cur];i;i=tov[i]) if(exi[i]&&typ[i]==0&&name[i]==a){ exi[i]=0; return; } printf("No such file!\n"); } void rmd() { string a=""; for(int i=6;i<len;i++) a+=opt[i]; for(int i=fr[cur];i;i=tov[i]) if(exi[i]&&typ[i]&&name[i]==a){ exi[i]=0; return; } printf("No such directory!\n"); } void mkd() { string a=""; for(int i=6;i<len;i++) a+=opt[i]; for(int i=fr[cur];i;i=tov[i]) if(exi[i]&&typ[i]&&name[i]==a){ printf("Directory already exists!\n"); return; } tov[++cnt]=fr[cur]; fr[cur]=cnt; exi[cnt]=1; typ[cnt]=1; name[cnt]=a; fa[cnt]=cur; } void ls(int pr) { if(!pr)return; ls(tov[pr]); if(exi[pr])cout<<name[pr]; if(exi[pr])printf(" <%c>\n",(typ[pr]?'D':'F')); } void work() { each(i,0,n){ getline(cin,opt); len=opt.size(); if(opt[0]=='c'&&opt[3]=='.') cdf(); else if(opt[0]=='c') cdD(); else if(opt[0]=='t') tou(); else if(opt[0]=='r'&&opt[2]=='d') rmd(); else if(opt[0]=='r') rmf(); else if(opt[0]=='m') mkd(); else ls(fr[cur]); } } void debug() { // } int main() { freopen(PROC".in","r",stdin); freopen(PROC".out","w",stdout); init(); work(); //debug(); return 0; }
相关文章推荐
- NOIP模拟题 [暴力][贪心][栈][dfs][找规律]
- NOIP模拟题[贪心][离散化][LIS]
- NOIP模拟题 kun 栈 贪心 解题报告
- [NOIP模拟题][杂题][贪心][水题]
- 【NOIP 模拟题】[T1]连锁店(贪心)
- NOIP模拟题 2017.7.3 - 模拟 - 贪心 - 记忆化搜索
- NOIP模拟题 2016.11.1 [模拟] [贪心] [杂题]
- NOIP模拟题[数论}[暴力][拆点]
- 【NOIP 模拟题】[山东多校联合模拟赛 day1 T1] 矩形计数(暴力)
- NOIP模拟题 2016.8.27 [贪心] [DP] [计数问题]
- 湖南NOIP集训模拟题DAY1 BY ExfJOE [贪心][DP][二分]
- 【NOIP 模拟题】[T2]分解数(线性筛+贪心)
- NOIP模拟题 River Path Word[排序][贪心][DP]
- 【NOIP模拟题】【贪心】【动态规划DP】2016.11.12第二题题解
- 【NOIP模拟题】【DP】【同余最短路】【暴力剪枝】2016.11.15 第二题 小L的牛栏 题解
- NOIP模拟题 2016.8.29 [树相关问题] [数论] [贪心] [拓扑排序]
- 【NOIP模拟题】【hash表】【暴力求解】2016.11.16 第三题 LGTB 与正方形 题解
- 【noip模拟题】天神下凡(贪心)
- NOIP模拟题 2016.10.13 [贪心] [记忆化搜索]
- 【贪心】NOIP模拟题“Kun”