题目链接:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=37
题目意思:
开始给定编号为0-n的数分别在1-n栈里,然后执行四种操作,求最后这n个栈中的数据情况
四种操作规则:
1.move a onto b
把a所在栈a上面的数据回归到初始状态,把b所在栈b上面的数据回归到初始状态,然后把a放到b上面
2.move a over b
把a所在栈a上面的数据回归到初始状态,然后把a放到b上面
3.pile a onto b
把b所在栈b上面的数据回归到初始状态,然后把a所在栈包括a元素在内的所有元素按在该栈的顺序不变,全部移到b所在的栈上
4.pile a over b
把a所在栈包括a元素在内的所有元素按在该栈的顺序不变,全部移到b所在的栈上
解题思路:
用栈来模拟执行过程,注意数据为0-n-1,回归的时候注意加一。细节详见代码
代码:
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<map> #define eps 1e-6 #define INF (1<<20) #define PI acos(-1.0) using namespace std; struct Stack //模拟栈 { int top; int save[100]; int pop() { return save[top--]; } int push(int n) { ++top; return save[top]=n; } bool empty() { if(top==0) return true; return false; } void clear() { top=0; } int finda(int a) { for(int i=1;i<=top;i++) //在栈中找数的位置 if(save[i]==a) return i; return 0; } }; Stack stack[100]; int n; int find(int a) //找数a属于哪一个栈 { for(int i=1;i<=n;i++) { int j=stack[i].finda(a); if(j) return i; } } void removeup(int local,int a) //将a上面的元素全部回归 { //while(stack[local].save[stack[local].top]!=a) int limit=stack[local].finda(a); for(int i=limit+1;i<=stack[local].top;i++) { int temp=stack[local].save[i]; stack[temp+1].push(temp); /* stack[temp+1].clear(); //注意回归时应与加一对应,坑死了 stack[temp+1].push(temp);*/ } stack[local].top=limit; //注意现在该栈的元素个数 return ; } void removewhole(int locala,int a,int localb) //将a所在栈包括a以及以上的所有元素全部按顺序移到b所在栈上 { int i=stack[locala].finda(a); //先找到a的位置 int temp=i; for(;i<=stack[locala].top;i++) { stack[localb].push(stack[locala].save[i]); } stack[locala].top=temp-1; //注意更新栈a的元素个数 return ; } void moveonto(int a,int b) { int tempa=find(a),tempb=find(b); if(tempa==tempb) return ; removeup(tempa,a); removeup(tempb,b); stack[tempb].push(a); //将a移向b stack[tempa].top--; return ; } void moveover(int a,int b) { int tempa=find(a),tempb=find(b); if(tempa==tempb) return ; removeup(tempa,a); stack[tempb].push(a); //将a移向b stack[tempa].top--; return ; } void pileonto(int a,int b) { int tempa=find(a),tempb=find(b); if(tempa==tempb) return ; removeup(tempb,b); removewhole(tempa,a,tempb); return ; } void pileover(int a,int b) { int tempa=find(a),tempb=find(b); if(tempa==tempb) return ; removewhole(tempa,a,tempb); } void print() { for(int i=1;i<=n;i++) { printf("%d:",i-1); if(!stack[i].empty()) { for(int j=1;j<=stack[i].top;j++) printf(" %d",stack[i].save[j]); } putchar('\n'); } return ; } int main() { int a,b; char com1[20],com2[20]; while(cin>>n) { for(int i=1;i<=n;i++) { stack[i].clear(); stack[i].push(i-1); } //print(); while(cin>>com1&&strcmp(com1,"quit")) { scanf("%d%s%d",&a,com2,&b); if(a==b) continue; if(strcmp(com1,"move")==0) { if(strcmp(com2,"onto")==0) moveonto(a,b); else moveover(a,b); } else { if(strcmp(com2,"onto")==0) pileonto(a,b); else pileover(a,b); } // print(); } print(); } return 0; }
package com.upon.common.view; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.util.AttributeSet; import android.widget.ImageView; import com.upon.xxxx.R; public class UponRotateImageView extends ImageView { private int mAngle; public UponRotateImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); loadAttributes(context, attrs); } public UponRotateImageView(Context context, AttributeSet attrs) { super(context, attrs); loadAttributes(context, attrs); } public UponRotateImageView(Context context) { super(context); } private void loadAttributes(Context context, AttributeSet attrs) { TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.RotateImageView); mAngle = arr.getInteger(R.styleable.RotateImageView_angle, 0); arr.recycle(); } public int getAngle() { return mAngle; } public void setAngle(int angle) { mAngle = angle; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int w = getDrawable().getIntrinsicWidth(); int h = getDrawable().getIntrinsicHeight(); double a = Math.toRadians(mAngle); int width = (int) (Math.abs(w * Math.cos(a)) + Math.abs(h * Math.sin(a))); int height = (int) (Math.abs(w * Math.sin(a)) + Math.abs(h * Math.cos(a))); setMeasuredDimension(width, height); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onDraw(Canvas canvas) { canvas.save(); canvas.rotate(mAngle % 360, getWidth() / 2, getHeight() / 2); getDrawable().draw(canvas); canvas.restore(); } }
attrs.xm文件中增加angle属性
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="RotateImageView"> <attr name="angle" format="integer" /> </declare-styleable> </resources>
使用UponRotateImageView
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:upon="http://schemas.android.com/apk/res/com.upon.xxxx" android:layout_width="wrap_content" android:layout_height="wrap_content" > <com.upon.common.view.UponRotateImageView android:id="@+id/bkg_img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="/blog_article/@drawable/conquer_nation_bkg/index.html" upon:angle="45" /> </RelativeLayout>
已有 0 人发表留言,猛击->>这里<<-参与讨论
ITeye推荐
- —软件人才免语言低担保 赴美带薪读研!—
linuxthreads管理线程原理详解
为什么A程序创建了10个线程, 但是ps时却会出现11个A进程了. 因为linuxthreads自动创建了一个管理线程.
当程序开始运行时, 并没有管理线程存在(因为尽管程序已经链接了pthread库, 但是未必会使用多线程).
程序第一次调用pthread_create时, linuxthreads发现管理线程不存在, 于是创建这个管理线程. 这个管理线程是进程中的第一个线程(主线程)的儿子.
然后在pthread_create中, 会通过pipe向管理线程发送一个命令, 告诉它创建线程. 即是说, 除主线程外, 所有的线程都是由管理线程来创建的, 管理线程是它们的父亲.
【一个线程退出】
于是, 当任何一个子线程退出时, 管理线程将收到SIGUSER1信号(这是在通过clone创建子线程时指定的). 管理线程在对应的sig_handler中会判断子线程是否正常退出, 如果不是, 则杀死所有线程, 然后自杀.
那么, 主线程怎么办呢? 主线程是管理线程的父亲, 其退出时并不会给管理线程发信号. 于是, 在管理线程的主循环中通过getppid检查父进程的ID号, 如果ID号是1, 说明父亲已经退出, 并把自己托管给了init进程(1号进程). 这时候, 管理线程也会杀掉所有子线程, 然后自杀.
可见, 线程的创建与销毁都是通过管理线程来完成的, 于是管理线程就成了linuxthreads的一个性能瓶颈.
创建与销毁需要一次进程间通信, 一次上下文切换之后才能被管理线程执行, 并且多个请求会被管理线程串行地执行.
【总结】
当一个线程退出时:
1.正常退出======== 其他线程继续运行。
2.非正常退出====== 进程结束。
当进程退出时:
进程和所有线程一起退出。
=======================================================
父子进程中若父进程退出,而不等待子进程,子进程会变为僵尸进程。