題目

問題描述

  Excel單元格的地址表示很有趣,它使用字母來表示列號。
  比如,
  A表示第1列,
  B表示第2列,
  Z表示第26列,
  AA表示第27列,
  AB表示第28列,
  BA表示第53列,
  ....


  當然Excel的最大列號是有限度的,所以轉換起來不難。
  如果我們想把這種表示法一般化,可以把很大的數字轉換爲很長的字母序列呢?


  本題目即是要求對輸入的數字, 輸出其對應的Excel地址表示方式。

樣例輸入

26

樣例輸出

Z

樣例輸入

2054

樣例輸出

BZZ

數據規模和約定

  我們約定,輸入的整數範圍[1,2147483647]


  峯值內存消耗(含虛擬機) < 256M
  CPU消耗 < 1000ms




  請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多餘內容。


  注意:
  main函數需要返回0;
  只使用ANSI C/ANSI C++ 標準;
  不要調用依賴於編譯環境或操作系統的特殊函數。
  所有依賴的函數必須明確地在源文件中 #include <xxx>
  不能通過工程設置而省略常用頭文件。


  提交程序時,注意選擇所期望的語言類型和編譯器類型。


  ------------------------------


  笨笨有話說:
  這有點像進制關係,又不完全是。好像末2位是以1當26,末3位是以1當26*26


  歪歪有話說:
  要是從字母序列轉數字還好點,倒過來有點麻煩,不過計算機跑得快啊。

#include<bits/stdc++.h>
using namespace std;  
#define ll long long
int b[1000000];
int main(){
	ll a ;
	cin>>a;int i=0;
	while(a){
		
		int yushu=a%26;//consider in aspects of yuanli
		if(yushu==0) yushu=26;
		a=(a-yushu)/26;
		b[i++]=yushu;
	}
	for(int j=i-1;j>=0;j--){
		cout<<char(b[j]+'A'-1);
	}
	return 0;
}

emmm.好久沒發博客了,從原理出發,別靠感覺亂寫。

問題描述

  兒童節那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友們。
  小明一共有N塊巧克力,其中第i塊是Hi x Wi的方格組成的長方形。


  爲了公平起見,小明需要從這 N 塊巧克力中切出K塊巧克力分給小朋友們。切出的巧克力需要滿足:


  1. 形狀是正方形,邊長是整數
  2. 大小相同


  例如一塊6x5的巧克力可以切出6塊2x2的巧克力或者2塊3x3的巧克力。


  當然小朋友們都希望得到的巧克力儘可能大,你能幫小Hi計算出最大的邊長是多少麼?

輸入格式

  第一行包含兩個整數N和K。(1 <= N, K <= 100000)
  以下N行每行包含兩個整數Hi和Wi。(1 <= Hi, Wi <= 100000)
  輸入保證每位小朋友至少能獲得一塊1x1的巧克力。

輸出格式

  輸出切出的正方形巧克力最大可能的邊長。

樣例輸入

2 10
6 5
5 6

樣例輸出

2

數據規模和約定

  峯值內存消耗(含虛擬機) < 256M
  CPU消耗 < 1000ms

 

#include<bits/stdc++.h>
using namespace std;
int x,y;
struct node{//錯誤代碼,靠直覺寫的,看來直覺不可信,因爲巧克力不可以拼在一起 
	int a,b;
}nod[100002];
bool cmp(node x,node y){
	return x.a<y.a;
}
bool check(int u){
	int res=nod[x].b-nod[u-1].b;
	if(res/nod[u].a>=y){
		return true;
	}
	else return false;
}
int main(){

	cin>>x>>y;
	for(int i=1;i<=x;i++){
		int o,p;
		cin>>o>>p;
		nod[i].a=min(o,p);
		nod[i].b=max(o,p);
	}
	for(int i=2;i<=x;i++){
		nod[i].b=nod[i].b+nod[i-1].b;
	}
	
	sort(nod+1,nod+x+1,cmp);
	int l=1,r=x;
	int mid;
	while(l<r){
		mid=(l+r)/2;
		if(check(mid)){
			l=mid;
		}
		else {
			r=mid-1;
		}
		
	}
	cout<<nod[mid].a;
	return 0;
}
#include<bits/stdc++.h>
using namespace std;
int h[100010];
int w[100010];int x,y;
bool check(int n){
	int res=0;
	for(int i=1;i<=x;i++){
		int x1=h[i]/n;
		int y2=w[i]/n;
		res+=x1*y2;
		
	} 
//	cout<<endl<<res<<"fe"<<n<<endl;
	if(res>=y) return true;
	else return false;
}
int main(){

	cin>>x>>y;int shu=0;
	for(int i=1;i<=x;i++){
		cin>>h[i]>>w[i];
		shu=max(shu,h[i]);
	}
//	cout<<shu<<endl;
	int l=1,r=shu+1;//爲了取到shu 
	int mid;
	while(l<(r-1)){
	//	cout<<l<<" "<<r<<endl;
		mid=(l+r)/2;
	//	cout<<mid<<endl;
		if(check(mid)){
			l=mid;
		}
		else r=mid;
	}
	cout<<l<<endl;
	return 0;
} 

emmm,寫的飛快,但是錯的一堆。

問題描述

  小明正在整理一批歷史文獻。這些歷史文獻中出現了很多日期。小明知道這些日期都在1960年1月1日至2059年12月31日。令小明頭疼的是,這些日期採用的格式非常不統一,有采用年/月/日的,有采用月/日/年的,還有采用日/月/年的。更加麻煩的是,年份也都省略了前兩位,使得文獻上的一個日期,存在很多可能的日期與其對應。


  比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。


  給出一個文獻上的日期,你能幫助小明判斷有哪些可能的日期對其對應嗎?

輸入格式

  一個日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9)

輸出格式

  輸出若干個不相同的日期,每個日期一行,格式是"yyyy-MM-dd"。多個日期按從早到晚排列。

樣例輸入

02/03/04

樣例輸出

2002-03-04
2004-02-03
2004-03-02

#include<bits/stdc++.h>
using namespace std;
set<string>e;
int a[2][13]={ 0,31,28,31,30,31,30,31,31,30,31,30,31,
0,31,29,31,30,31,30,31,31,30,31,30,31
				
};
void check(int y,int m,int d){
//	cout<<y<<" "<<m<<" "<<d<<endl;
	y+=1900;int f=0;string s;char c[15];
	if(y<1960) y+=100;//
	if(y%400==0||(y%100!=0&&y%4==0)) f=1;
	if(m>=1&&m<=12){
		if(d>=1&&d<=a[f][m]){
			sprintf(c,"%d-%02d-%02d",y,m,d);
			if(e.count(s=c)==0){
				e.insert(s);
			}
		}
		
	}
	
}
int main(){
	int a1,a2,a3;
	scanf("%2d/%2d/%2d",&a1,&a2,&a3);//格式控制要會靈活使用 
//	cout<<a1<<"fe"<<a2<<"fe"<<a3<<endl;
	check(a1,a2,a3);
	check(a3,a1,a2);
	check(a3,a2,a1);
	for(set<string>::iterator it=e.begin();it!=e.end();it++){//審題很重要 
		cout<<*it<<endl;//集合自己便會排序 
	} 
	return 0;
} 

Alice and Bob

Description

 

AliceAlice和BobBob在一棵有根樹上移動棋子,每次將棋子向所在點的其中一個兒子移動

不能移動就算失敗,AliceAlice先手,BobBob後手,兩人均採取最優策略,最後的贏家是誰

Input

 

輸入第一行爲一個整數nn,表示有根樹的節點數目(1 \le n \le 100000)(1≤n≤100000)

接下來n-1n−1行,每行兩個數字u,vu,v,表示點uu和點vv之間存在一條邊

接下來一行爲一個整數mm,表示詢問次數(1 \le m \le 10)(1≤m≤10)

接下來mm行,每行只有一個整數xx,表示本次詢問的樹的根節點的標號(1 \le x \le n)(1≤x≤n)

(多次詢問時,只是根節點有變化,樹的邊是不變的)

Output

 

對於每次詢問,輸出一行,如果是先手勝,輸出"Alice",否則輸出"Bob"(不含引號)

Sample Input 1 

3
1 2
2 3
1
1

Sample Output 1

Bob

Sample Input 2 

5
1 2
1 3
3 4
4 5
2
2
4

Sample Output 2

Bob
Alice

Source

牛客小白賽2

#include<bits/stdc++.h>
using namespace std;
bool vis[100010];
vector<int >gg[100010];//不熟練 
bool win[100010];
bool dfs(int a){
	vis[a]=1;int son=0;int win_son=0;
	for(int i=0;i<gg[a].size();i++){
		int u=gg[a][i];
		if(vis[u]) continue;
		son++;
		if(dfs(u)) win_son++;
		
	}
	if(son==win_son) win[a]=0;
	else win[a]=1;
	return win[a];
}
int main(){
	int n;int u,v;
	cin>>n;
	for(int i=1;i<n;i++){
		cin>>u>>v;
		gg[u].push_back(v);
		gg[v].push_back(u);
		
	}
	int m;
	cin>>m;
	while(m--){
		int q;
		memset(vis,0,sizeof(vis));
		
		cin>>q;
		if(dfs(q))
		cout<<"Alice\n";
		else cout<<"Bob"<<endl;
		
	}
	return 0;
	
}

Max answer

Description

 

給出一個長度爲nn的數字序列aa,將其任意排序,使得\sum_{i = 1}^{n}|a_{i\%n+1} - a_{i}|∑i=1n​∣ai%n+1​−ai​∣最大

Input

 

第一行一個整數TT,表示有TT組數據(1 \le T \le 10)(1≤T≤10)

對於每組數據,輸入第一行只有一個整數n(1 \le n \le 100000)n(1≤n≤100000)

第二行輸入nn個整數表示ai(-(10^9+7) \le ai \le 10^9+7)ai(−(109+7)≤ai≤109+7)

Output

 

對於每一組數據,輸出"Case x: ans"(不含引號)

xx表示第xx組數據,從11開始編號,ansans表示答案

Sample Input 1 

2
5
7 3 15 12 8
7
-2 0 8 9 -5 3 10

Sample Output 1

Case 1: 34
Case 2: 68

Source

牛客小白賽2

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int a[100010];
int b[100010];
int main(){
	int t;
	cin>>t;int ccase=0;
	while(t--){
		int n;scanf("%d",&n);int sum=0;
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
		}
		sort(a+1,a+n+1);
		int i,j,k;
		//cout<<"fefe";
		for(i=n,j=1,k=1;i>j;i--,j++){
			b[k++]=a[i];
			b[k++]=a[j];
			//cout<<"fef";
		}
		//cout<<k<<endl;
		//cout<<"fefefef";
	//	for(int i=1;i<k;i++)
	//		cout<<b[i]<<" ";
		if(i==j) b[k++]=a[j];ll res=0;
		b[0]=b[k-1];
		for(int q=1;q<k;q++)
		{
			res+=abs(b[q]-b[q-1]);
		}
		cout<<"Case "<<++ccase<<": ";
		cout<<res<<endl;
		
	
/*	if(n%2==1) 
{
		for(int i=1;i<=n/2;i++){
		sum-=a[i]*2;
	}
	for(int i=(n/2)+1;i<=n;i++){
		sum+=a[i];
	}
	cout<<sum<<endl;
}*/
}
return 0;
	
}

反轉

Description

 

有一個nn個元素的數組,每個元素初始均爲00

有mm條操作指令,操作一:將[l,r][l,r]區間內的數字進行反轉(00變成11,11變成00)

操作二:詢問第ii個元素的值

Input

 

輸入第一行包含兩個整數n,mn,m,表示數組的長度和指令的條數

接下來mm行,每行第一個數tt表示操作的種類:

  • 若t=1t=1,則接下來有兩個數l,rl,r,表示區間[l,r][l,r]的每個數均反轉
  • 若t=2t=2,則接下來只有一個數ii,表示詢問的下標。

(1\le n \le 10^5, 1 \le m \le 5*10^5,l \le r)(1≤n≤105,1≤m≤5∗105,l≤r)

Output

 

每個操作二輸出一行,表示每次操作二的回答

Sample Input 1 

20 10
1 1 10
2 6
2 12
1 5 12
2 6
2 15
1 6 16
1 11 17
2 12
2 6

Sample Output 1

1
0
0
0
1
1

Source

LOJ-10117

#include<bits/stdc++.h>
using namespace std;
int a[100010];
int n;
int que(int q){
	int res=0;
	for(int i=q;i;i-=i&-i){
		res+=a[i];
	}
	return res;
}
void insert(int x,int y){
	for(int i=x;i<=n;i+=i&-i){
		a[i]+=y;
	}
	return ;
}
int main (){
	int m;
	cin>>n>>m;//那就說明要樹狀數組減少複雜度, 
	while(m--){
		int q,num;
		cin>>q>>num;
		if(q==1){
			int r;cin>>r;int shu;
			insert(num,1);
			insert(r+1,-1);//不包含端點 
			
		}
		else {
			
			cout<<(que(num)&1)<<endl; // 
			
		}
	
	}
	return 0;
}

數列分段

Description

 

給定長度爲nn的正整數數列aa,將其分成mm段,要求每段連續,且每段的和的最大值最小

例如數列4\ 2\ 4\ 5\ 14 2 4 5 1要分成33段

若分成[4\ 2][4\ 5][1][4 2][4 5][1],每段和分別爲6,9,16,9,1,和的最大值爲99

若分成[4][2\ 4][5\ 1][4][2 4][5 1],每段和分別爲4,6,64,6,6,和的最大值爲66

並且無論如何分段,最大值不會小於66,所以答案爲66。

Input

 

輸入第一行包含兩個整數n,m(1 \le M \le N \le 10^5)n,m(1≤M≤N≤105)

第二行包含nn個整數表示給定的正整數數列ai(1 \le ai \le 10^9\ \ \sum_{i = 1}^{n}ai <= 10^9)ai(1≤ai≤109  ∑i=1n​ai<=109)

Output

 

輸出僅包含一個整數表示每段和最大值最小爲多少

Sample Input 1 

5 3
4 2 4 5 1

Sample Output 1

6

Source

LOJ-10014

#include<bits/stdc++.h>
using namespace std;
int a[100010];
int n;int m;
#define ll long long
int check(int shu){
	int summ=0;int q=1;//bool flag=false;
	for(int i=1;i<=n;i++){
		if(summ+a[i]<=shu){//條件寫錯了 
			summ+=a[i];
		//	cout<<summ<<endl;
			
		}
		else {
			//flag=true;
			q++;
			summ=a[i];
		//	cout<<"fe"<<endl;
			
		}
		
		
	}
	return q;
	
}
int main(){

	cin>>n>>m;int sum=0;int maxxx=0;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum+=a[i];
		maxxx=max(maxxx,a[i]);
	}
	int r=(sum-m+1);//這些都無所謂 
	maxxx=max(maxxx,(sum+m-1)/m);//該選擇最大的元素爲最小,而我找了平均。 
	//cout<<sum<<endl;
	
	//r=sum;
	int l=maxxx;
	int mid;
	while(l<r){
		mid=(l+r)/2;
		if(check(mid)<=m)
		r=mid;//我錯了 ,這個中間的總是忽略 
		else 
		l=mid+1;
	}
	cout<<l<<endl;
	return 0;
	
}

帶分數

Description

 

100100可以表示成帶分數的形式:100 = 3\frac{69258}{714}100=371469258​

還可以表示成:100 = 82\frac{3546}{197}100=821973546​

注意:帶分數中,數字1-91−9分別出現且只出現一次(不包括00)

類似這樣的帶分數,100100有1111種表示法

那麼數字nn有多少種表示法呢

Input

 

第一行一個整數TT,表示有TT組數據(1 \le T \le 10)(1≤T≤10)

對於每組數據,輸入只有一個整數n(1 \le n \le 100000)n(1≤n≤100000)

Output

 

對於每一組數據,輸出"Case x: ans"(不含引號)

xx表示第xx組數據,從11開始編號,ansans表示答案

Sample Input 1 

3
100
105
37

Sample Output 1

Case 1: 11
Case 2: 6
Case 3: 6

Source

藍橋杯

#include<bits/stdc++.h>
using namespace std;
int b[10];
int a[10];
int main(){
	int t;
	cin>>t;
	b[0]=1;
	for(int i=1;i<=9;i++){
		b[i]=b[i-1]*10;
	}
	int ccase=0;
 	while(t--){
		int n;
		cin>>n;int ans=0;
		
		for(int i=1;i<=9;i++)
		a[i]=i;
		do{
			int num=0;
			for(int i=1;i<=9;i++){
				num=num*10+a[i];
			}
			for(int i=1;i<=7;i++){
				int num1=num/b[9-i];
				int num2=num%b[9-i];
				if(num1>n) break;
				for(int j=i+1,k=1;j<=9;j++,k++){
					int fir=num2/b[k];
					int sec=num2%b[k];
					if(fir<sec) break;
					if(fir%sec==0&&num1+fir/sec==n){
						ans++;
					}
				}
				
			}
		}while(next_permutation(a+1,a+10)) ;
		cout<<"Case "<<++ccase<<": ";
		cout<<ans<<endl;
	}
	return 0;
}

全排列要會用,二分注意端點,先要判斷是否要找規律,再是博弈的核心要抓住,樹狀數組等一些常規數據結構要靈活。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章