关键代码为重写Layout.Factory.onCreateView()方法自定义布局,不复杂,所以不多说,简单的几段代码:
public class MenuAct extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); MenuInflater inflater = new MenuInflater(getApplicationContext()); inflater.inflate(R.menu.menu, menu); setMenuBackground(); return true; } public boolean onOptionsItemSelected(MenuItem item) { String info = ""; switch (item.getItemId()) { case R.id.menu_add: info = "Add"; break; case R.id.menu_delete: info = "Delete"; break; case R.id.menu_home: info = "Home"; break; case R.id.menu_help: info = "Help"; break; default: info = "NULL"; break; } Toast toast = Toast.makeText(this, info, Toast.LENGTH_SHORT); toast.show(); return super.onOptionsItemSelected(item); } // 关键代码为重写Layout.Factory.onCreateView()方法自定义布局 protected void setMenuBackground() { MenuAct.this.getLayoutInflater().setFactory(new android.view.LayoutInflater.Factory() { /** * name - Tag name to be inflated.<br/> * context - The context the view is being created in.<br/> * attrs - Inflation attributes as specified in XML file.<br/> */ public View onCreateView(String name, Context context, AttributeSet attrs) { // 指定自定义inflate的对象 if (name.equalsIgnoreCase("com.android.internal.view.menu.IconMenuItemView")) { try { LayoutInflater f = getLayoutInflater(); final View view = f.createView(name, null, attrs); new Handler().post(new Runnable() { public void run() { // 设置背景图片 view.setBackgroundResource(R.drawable.menu_background); } }); return view; } catch (InflateException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } return null; } }); } }
/res/menu/menu.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/menu_add" android:title="Add" android:icon="@drawable/menu_add"></item> <item android:id="@+id/menu_delete" android:title="Delete" android:icon="@drawable/menu_delete"></item> <item android:id="@+id/menu_home" android:title="Home" android:icon="@drawable/menu_home"></item> <item android:id="@+id/menu_help" android:title="Help" android:icon="@drawable/menu_help"></item> </menu>
题意:一条街从西到东住着N(3 <= N <= 20000)位乒乓球选手,每位选手有一个属于自己的等级,3个人,2人比赛,1人当裁判,裁判要住在这2个人之间,且裁判的等级也要在这2人之间,问共能举行几场比赛?
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=26&page=show_problem&problem=2330
——>>AC的感觉真是不错!艰辛!!!从2到N-1依次选i为裁判,求其左边有几人比裁判的等级低,记为c[i],再求右边有几人比裁判等级低,记为d[i],比赛场数为c[i]*(N-i-d[i]) + (i-1-c[i])*d[i],当然啦,求c[i]、d[i]时不可一个一个地循环扫,否则TLE。设等级存在数组a[]里,设等级标记存在数组x[],当扫到i当裁判时,该裁判的等级为a[i],等级比他低的等级有a[i]-1, a[i]-2, ...于是扫描等级数组x[],若x[j] == 1,说明等级为j的选手已存在,将前a[i]-1个x[]加起来,就是c[i],从后往前扫就可得d[i],此过程通过树状数组即二叉索引树BIT实现。要注意:c[i]*(N-i-d[i]) + (i-1-c[i])*d[i]可能大于2147483647,所以此处应用64位整数来存。
#include <iostream> #include <string.h> using namespace std; const int maxn = 20000 + 10; //人数3 <= N <= 20000 const int maxnn = 100000 + 10; //等级 [1, 100000] int a[maxn], c[maxn], d[maxn], x[maxnn], BIT[maxnn], N; //a[i]为i的等级,c[i]为第i个人的西边等级比他低的人数,d[i]为第i个人的东边等级比他低的人数,x[i]为目前为止等级为i的人是否存在,BIT[i]为二叉索引树第i个条的长度 int lowbit(int i) //数i的二进制表示的从右边开始第一个1对应的值 { return i&-i; } int sum(int i) //BIT求x的前i项和 { int ret = 0; while(i > 0) { ret += BIT[i]; i -= lowbit(i); } return ret; } void add(int i, int d) //当修改x[i]的时候,对应修改二叉索引树中BIT数组 { while(i <= maxnn-1) //注意:这个maxnn-1千万别写成N,需要 >= 100000 因为这是对等级来说的,不是对选手来说的! { BIT[i] += d; i += lowbit(i); } } int main() { int T, i; cin>>T; while(T--) { memset(x, 0, sizeof(x)); //初始化x为0 memset(BIT, 0, sizeof(BIT)); //初始化BIT为0,因为x数组为0,无论多少个0相加还是0 cin>>N; for(i = 1; i <= N; i++) cin>>a[i]; for(i = 1; i <= N; i++) //从西往东求第i个人的西边有几个比他等级低的选手,即c[i] { c[i] = sum(a[i]-1); //求和 x[a[i]] = 1; //标记这个等级已存在 add(a[i], 1); //加到BIT去 } memset(x, 0, sizeof(x)); //再次初始化不可少! memset(BIT, 0, sizeof(BIT)); //再次初始化不可少! for(i = N; i >= 1; i--) //从东往西求第i个人的东边有几个比他等级低的选手,即d[i] { d[i] = sum(a[i]-1); //求和 x[a[i]] = 1; //标记这个等级已存在 add(a[i], 1); //加到BIT去 } long long sum = 0; //小心溢出呀!!! for(i = 2; i <= N-1; i++) sum += c[i]*(N-i-d[i]) + (i-1-c[i])*d[i]; //乘法原理与加法原理 cout<<sum<<endl; } return 0; }
在输入东西的时候,如果想限制最大字数,可以用下面方法:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if ([string isEqualToString:@"\n"]){
return YES;
}
NSString * aString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if (self.searchTextField == textField)
{
if ([aString length] > 5) {
textField.text = [aString substringToIndex:5];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
message:@"超过最大字数不能输入了"
delegate:nil
cancelButtonTitle:@"Ok"
otherButtonTitles:nil, nil];
[alert show];
[alert release];
return NO;
}
}
return YES;
}