目錄
A:HDU 5933
B:HDU 5934
C:HDU 5935
D:HDU 6312
E:HDU 6308
F: HDU 5938
G:HDU 5606
H:HDU 1404
I:HDU 5358
J:HDU 1097
K:HDU 5943
A :ArcSoft's Office Rearrangement
題目:
ArcSoft, Inc. is a leading global professional computer photography and computer vision technology company.
There are NN working blocks in ArcSoft company, which form a straight line. The CEO of ArcSoft thinks that every block should have equal number of employees, so he wants to re-arrange the current blocks into KK new blocks by the following two operations:
- merge two neighbor blocks into a new block, and the new block's size is the sum of two old blocks'.
- split one block into two new blocks, and you can assign the size of each block, but the sum should be equal to the old block.
Now the CEO wants to know the minimum operations to re-arrange current blocks into KK block with equal size, please help him.
Input
First line contains an integer TT, which indicates the number of test cases.
Every test case begins with one line which two integers NN and KK, which is the number of old blocks and new blocks.
The second line contains NN numbers a1a1, a2a2, ??, aNaN, indicating the size of current blocks.
Limits
1≤T≤1001≤T≤100
1≤N≤1051≤N≤105
1≤K≤1051≤K≤105
1≤ai≤1051≤ai≤105
Output
For every test case, you should output 'Case #x: y', where x indicates the case number and counts from 1 and y is the minimum operations.
If the CEO can't re-arrange KK new blocks with equal size, y equals -1.
Sample Input
3
1 3
14
3 1
2 3 4
3 6
1 2 3
Sample Output
Case #1: -1
Case #2: 2
Case #3: 3
題意:
某公司有 n 個(gè)工作區(qū)沙峻,這 n 個(gè)工作區(qū)依次分布在一條直線上∶欧啵現(xiàn)在這個(gè)公司的老大 想要重新整治一下工作區(qū)倡勇,將原有的工作區(qū)分成 k 個(gè)工作區(qū)并且要求每個(gè)工作區(qū)當(dāng)中的人數(shù) 相同俗或。問最少操作次數(shù)是幾次凌箕? 操作有兩種枪萄,操作一:將兩個(gè)相鄰工作區(qū)合并成一個(gè)新的工作區(qū),新的工作區(qū)工作人員數(shù)等 于兩個(gè)工作區(qū)的工作人員數(shù)的和史飞;操作二:將一個(gè)工作區(qū)拆分成兩個(gè)工作區(qū)尖昏,拆分成的兩個(gè) 工作區(qū)的人數(shù)和等于原工作區(qū)人數(shù)。
思路:
人數(shù)不為 k 的整數(shù)倍一定不行构资,人數(shù)為 k 的整數(shù)倍一定可以抽诉。因?yàn)橹荒芟噜弮蓚€(gè)工作 區(qū)進(jìn)行合并,所以考慮順序遍歷貪心吐绵。每次對當(dāng)前格進(jìn)行拆分掸鹅,多余的向后合并,注意如果 當(dāng)前格是整數(shù)倍可以少進(jìn)行一次拆分拦赠。
題解:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,k,a[100010];
int main(){
int T;
scanf( "%d" , &T );
for( int cas=1 ; cas<=T ; cas++ ){
scanf( "%lld%lld" , &n , &k );
ll sum=0;
for( int i=1 ; i<=n ; i++ ){
scanf( "%lld" , &a[i] );
sum=sum+a[i];
}
if( sum%k==0 ){
ll ans=0,ave=sum/k;
for( int i=1 ; i<=n ; i++ ){
if( a[i]%ave==0 ){
ans += a[i]/ave-1;
}else{
ans += a[i]/ave+1;
}
a[i+1] += a[i]%ave;
}
printf( "Case #%d: %lld\n" , cas , ans );
}else{
printf( "Case #%d: -1\n" , cas );
}
}
return 0;
}
我參考的博客:
1.https://blog.csdn.net/yu121380/article/details/77473358(和平均數(shù)比較)
2.https://blog.csdn.net/qq_36651153/article/details/77169824(從左向右貪心)
3.https://www.cnblogs.com/Coolxxx/p/6011351.html
(無解的情況是N個(gè)區(qū)間的總大小s mod M ! = 0, 其實(shí)題目就是給你一個(gè)總長位s的N個(gè)區(qū)間巍沙,要求你合并相鄰的兩個(gè)或拆開一個(gè)大區(qū)間,使得最后的每個(gè)區(qū)間大小都為s/M荷鼠。那么如果原先的分界線和最終的分界線相同句携,那么就不必對這個(gè)分界線進(jìn)行合并。有解的時(shí)候可以知道每個(gè)新區(qū)間的大小x允乐,所以只要看Ai的前綴和里是否有x的倍數(shù)矮嫉,如果有則這個(gè)位置不用操作削咆。總共需要合并N-1次,拆分M-1次蠢笋,扣掉不需要的操作t*2次拨齐,即為答案。)
4.https://blog.csdn.net/huatian5/article/details/52967458(思維題)
我的代碼:(切記long long )
#include<vector>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<algorithm>
#include<stdlib.h>
#define ll long long
using namespace std;
const double eps=1e-7;
const int maxn=300050;
ll y[maxn],x[maxn];
int main(){
int t;
int a,b;
int count=0;
scanf("%d",&t);
while(t--){
scanf("%d%d",&a,&b);
ll sum=0;
for(int i=1;i<=a;i++){
scanf("%d",&y[i]);
x[i]=x[i-1]+y[i];
sum+=y[i];
}
if(sum%b)printf("Case #%d: -1\n",++count);
else {
ll cnt=0;ll avg=sum/b;
for(int i=1;i<a;i++)
{
if(x[i]%avg==0)
cnt++;
}
ll step=a-1+b-1-2*cnt;
printf("Case #%d: %lld\n",++count,step);
}
}
return 0;
}
B - Bomb(有向圖)
原題地址:http://acm.hdu.edu.cn/showproblem.php?pid=5934(hdu5934)
There are NN bombs needing exploding.
Each bomb has three attributes: exploding radius riri, position (xi,yi)(xi,yi) and lighting-cost cici which means you need to pay cici cost making it explode.
If a un-lighting bomb is in or on the border the exploding area of another exploding one, the un-lighting bomb also will explode.
Now you know the attributes of all bombs, please use the minimum cost to explode all bombs.
Input
First line contains an integer TT, which indicates the number of test cases.
Every test case begins with an integers NN, which indicates the numbers of bombs.
In the following NN lines, the ith line contains four intergers xixi, yiyi, riri and cici, indicating the coordinate of ith bomb is (xi,yi)(xi,yi), exploding radius is riri and lighting-cost is cici.
Limits
- 1≤T≤201≤T≤20
- 1≤N≤10001≤N≤1000
- ?108≤xi,yi,ri≤108?108≤xi,yi,ri≤108
- 1≤ci≤1041≤ci≤104
Output
For every test case, you should output 'Case #x: y', where x indicates the case number and counts from 1 and y is the minimum cost.
Sample Input
1
5
0 0 1 5
1 1 1 6
0 1 1 7
3 0 2 10
5 0 1 4
Sample Output
Case #1: 15
題意:
有 n 個(gè)炸彈昨寞,每個(gè)炸彈具有三個(gè)屬性值:坐標(biāo)(x,y)引爆半徑 r 以及引爆成本 c瞻惋。
當(dāng) 引爆一枚炸彈時(shí),這枚炸彈會(huì)同時(shí)引爆其爆炸半徑內(nèi)的所有炸彈援岩。比如:炸彈 A 可以引爆 炸彈 B歼狼,炸彈 B 可以引爆炸彈 C,那么如果你引爆炸彈 A 即可引爆炸彈 A,B,C享怀。問引爆所有 炸彈的最小成本羽峰。思路:
如果炸彈 A 可以引爆炸彈 B,則從炸彈 A 向炸彈 B 畫一條連線添瓷,整個(gè)炸彈圖將會(huì)變成 一個(gè)有向圖梅屉。對于有向圖只要引爆那些入度為 0 的點(diǎn)就可以將整個(gè)炸彈圖全部引爆,也就是 最小成本鳞贷。但是有一種情況是需要特殊處理的坯汤,有向圖成環(huán)了。下面這種情況看似沒有任何 一個(gè)入度為 0 的點(diǎn)悄晃,但是需要引爆環(huán)中任意一點(diǎn)才可以引爆所有炸彈玫霎。最終的結(jié)論就是:對 有向圖進(jìn)行強(qiáng)連通分量縮點(diǎn)凿滤,縮點(diǎn)后將所有入度為 0 的點(diǎn)成本相加妈橄。
![tps://upload-images.jianshu.io/upload_images/16020496-decea51748505d81.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
題解:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
int n;
struct point{
ll x,y,r,c;
}p[1010];
int tol,head[1010];
struct edge{
int to,next;
}es[1000010];
void init(){
tol = 0; memset( head , -1 , sizeof(head) );
}
void addedge( int u , int v ){
es[tol].to = v;
es[tol].next = head[u];
head[u] = tol++;
}
bool ok( int a , int b ){
ll dx = p[a].x-p[b].x;
ll dy = p[a].y-p[b].y;
ll dd = p[a].r*p[a].r;
if( dx*dx+dy*dy<=dd ) return true;
else return false;
}
int low[1010],dfn[1010],Stack[1010],belong[1010],num[1010],pri[1010],indeg[1010];
int index,top,scc;
bool instack[1010];
void dfs( int u ){
int v;
low[u] = dfn[u] = ++index;
Stack[top++] = u;
instack[u] = true;
for( int i=head[u] ; i!=-1 ; i=es[i].next ){
v = es[i].to;
if( !dfn[v] ){
dfs( v );
if( low[u]>low[v] ) low[u] = low[v];
}else if( instack[v]&&low[u]>dfn[v] ){
low[u] = dfn[v];
}
}
if( low[u]==dfn[u] ){
scc++;
do{
v = Stack[--top];
instack[v] = false;
belong[v] = scc;
num[scc]++;
pri[scc] = min( pri[scc] , (int)p[v].c );
}while( v!=u );
}
}
void tarjan( int n ){
memset( dfn , 0 , sizeof(dfn) );
memset( instack , false , sizeof(instack) );
memset( num , 0 , sizeof(num) );
memset( pri , inf , sizeof(pri) );
memset( indeg , 0 , sizeof(indeg) );
index = scc = top = 0;
for( int i=1 ; i<=n ; i++ ){
if( !dfn[i] ) dfs(i);
}
}
int main(){
int T;
scanf( "%d" , &T );
for( int cas=1 ; cas<=T ; cas++ ){
scanf( "%d" , &n );
for( int i=1 ; i<=n ; i++ ){
scanf( "%lld%lld%lld%lld" , &p[i].x , &p[i].y , &p[i].r , &p[i].c );
}
init();
for( int i=1 ; i<=n ; i++ ){
for( int j=1 ; j<=n ; j++ ){
if( i==j ) continue;
if( ok( i , j ) ) addedge( i , j );
}
}
tarjan( n );
for( int u=1 ; u<=n ; u++ ){
for( int i=head[u] ; i!=-1 ; i=es[i].next ){
int v = es[i].to;
if( belong[u]==belong[v] ) continue;
indeg[belong[v]]++;
}
}
int ans = 0;
for( int i=1 ; i<=scc ; i++ ){
if( indeg[i]==0 ) ans += pri[i];
}
printf( "Case #%d: %d\n" , cas , ans );
}
return 0;
}
C - Car
Ruins is driving a car to participating in a programming contest. As on a very tight schedule, he will drive the car without any slow down, so the speed of the car is non-decrease real number.
Of course, his speeding caught the attention of the traffic police. Police record NN positions of Ruins without time mark, the only thing they know is every position is recorded at an integer time point and Ruins started at 00.
Now they want to know the minimum time that Ruins used to pass the last position.
Input
First line contains an integer TT, which indicates the number of test cases.
Every test case begins with an integers NN, which is the number of the recorded positions.
The second line contains NN numbers a1a1, a2a2, ??, aNaN, indicating the recorded positions.
Limits
1≤T≤1001≤T≤100
1≤N≤1051≤N≤105
0<ai≤1090<ai≤109
ai<ai+1ai<ai+1
Output
For every test case, you should output 'Case #x: y', where x indicates the case number and counts from 1 and y is the minimum time.
Sample Input
1
3
6 11 21
Sample Output
Case #1: 4
題意:
有一輛無敵拉風(fēng)的駕駛汽車,只能勻速或者加速翁脆。因?yàn)檫@個(gè)拉風(fēng)的特性眷蚓,這輛駕駛汽 車成功的引起了交警的注意,被記錄下 n 個(gè)時(shí)間整點(diǎn)的位置數(shù)據(jù)(位置數(shù)據(jù)是實(shí)數(shù))反番。交警 還知道開著這輛汽車的是個(gè)飆車狂沙热,喜歡極致快速。現(xiàn)在交警想要知道這個(gè)飆車狂花了多少 時(shí)間從位置 0 開始經(jīng)過這 n 個(gè)點(diǎn)罢缸。即:問從 0 開始不減速到達(dá)最后一個(gè)點(diǎn)的最短時(shí)間篙贸。
思路:
由于不能減速,所以從最后一個(gè)點(diǎn)開始往前走枫疆。最后一段距離爵川,一定是只花了一秒鐘, 依次從后往前推算即可息楔。
題解:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-8;
int n; double a[100010];
int main(){
int T;
scanf( "%d" , &T );
for( int cas=1 ; cas<=T ; cas++ ){a
scanf( "%d" , &n );
a[0] = 0;
for( int i=1 ; i<=n ; i++ ){
scanf( "%lf" , &a[i] );
}
for( int i=n ; i>=1 ; i-- ){
a[i] = a[i]-a[i-1];
}
ll ans = 1,tmp; double v = a[n];
for( int i=n-1 ; i>=1 ; i-- ){
tmp = ceil(a[i]/v-eps);
ans += tmp;
v = a[i]/tmp;
}
printf( "Case #%d: %lld\n" , cas , ans );
}
return 0;
}
我參考的博客:
1.https://blog.csdn.net/EventQueue/article/details/52995941(貪心策略寝贡,倒著看扒披,從后往前,后面的速度盡可能的大圃泡,這樣才能保證總的時(shí)間最短)
2.https://blog.csdn.net/mengxiang000000/article/details/52965196
3.https://blog.csdn.net/mrlry/article/details/53046532
4.https://www.cnblogs.com/Coolxxx/p/6011409.html (首先可以知道答案必為整數(shù)碟案,并且每一段距離都是勻速的。從后往前看颇蜡,最后一段距離X[N]-X[N-1]必然花了t=1s的時(shí)間(沒有約束條件价说,速度可以任意加),V=X[N]-X[N-1]澡匪。那么在它之前的距離X‘熔任,只要滿足速度V‘<V即可,那么把X’均分成t段唁情,每段時(shí)間為1疑苔,行走距離V‘,只要V’*t恰好>X‘即可甸鸟。這樣往前遞推惦费,每一段的速度都不能超過前面。注意精度問題 抢韭。)
5.https://blog.csdn.net/qingshui23/article/details/52973229
我的代碼:
#include<vector>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<algorithm>
#include<stdlib.h>
#define ll __int64
using namespace std;
const double eps=1e-7;
const int maxn=300050;
ll a[maxn];
void swap(int a,int b){
int temp;
temp=a;
a=b;
b=temp;
}
int main(){
int n,t;
int count=0;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
a[0]=0;
for(int i=1;i<=n;i++)
scanf("%I64d",&a[i]);
ll sum=0;
ll fenzi,fenmu;
for(int i=n;i>=1;i--)
{
if(i==n)
{
sum++;
fenzi=a[i]-a[i-1];
fenmu=1;
}
else
{
ll dis=a[i]-a[i-1];
fenmu*=dis;
swap(fenzi,fenmu);
ll tmpp=fenzi/fenmu+1;
if(fenzi%fenmu==0)tmpp--;
sum+=tmpp;
fenzi=dis;
fenmu=tmpp;
}
}
printf("Case #%d: ",++count);
printf("%I64d\n",sum);
}
return 0;
}
D - Game(簽到題)
Alice and Bob are playing a game.
The game is played on a set of positive integers from 1 to n.
In one step, the player can choose a positive integer from the set, and erase all of its divisors from the set. If a divisor doesn't exist it will be ignored.
Alice and Bob choose in turn, the one who cannot choose (current set is empty) loses.
Alice goes first, she wanna know whether she can win. Please judge by outputing 'Yes' or 'No'.
Input
There might be multiple test cases, no more than 10. You need to read till the end of input.
For each test case, a line containing an integer n. (1≤n≤5001≤n≤500)
Output
A line for each test case, 'Yes' or 'No'.
Sample Input
1
Sample Output
Yes
題意:
博弈界忠實(shí)老玩家 Alice 和 Bob 又發(fā)明了一款新的博弈游戲薪贫。這個(gè)游戲是這個(gè)樣子的 有一個(gè)集合集合內(nèi)有 n 個(gè)數(shù)依次為 1,2刻恭,3瞧省,。鳍贾。鞍匾。,n骑科。每個(gè)玩家每次可以從集合中選一個(gè)數(shù) 字橡淑,同時(shí)將集合內(nèi)該數(shù)的所有因子刪除。老規(guī)矩最后不能操作的玩家敗北咆爽。由于 Alice 和 Bob 博弈游戲玩多了所以這次 Alice 和 Bob 打算當(dāng)一次云玩家梁棠,只 BB 游戲的輸贏自己不玩。問 給定 n 如果先手贏輸出 Yes 先手?jǐn)≥敵?No斗埂。
思路:
1 這個(gè)數(shù)字很特別它是所有數(shù)字的因子符糊,你選那個(gè)數(shù)字這個(gè)一定會(huì)被刪除。在 2,3,4,…,n 內(nèi)選一個(gè)數(shù)字和在 1,2,3,…,n 內(nèi)選一個(gè) 2 到 n 的數(shù)字這個(gè)游戲是一毛一樣的呛凶。如果 2,3,4,…,n 這個(gè)游戲先手能玩贏男娄,那么在 2,3,4,…,n 內(nèi)選一個(gè)數(shù)字即可。如果 2,3,4,…,n 這個(gè)游 戲先手贏不了,那選個(gè) 1 把這個(gè)臭垃圾給對手吃沪伙。反正先手必贏(攤手瓮顽。
AC代碼:
#include<vector>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<algorithm>
#include<stdlib.h>
#define ll __int64
using namespace std;
const double eps=1e-7;
const int maxn=300050;
char gd[6];
int main(){
int t, h, m;
vector<int>q;
while(cin>>t)
{
printf("Yes\n");
}
return 0;
}
E - Time Zone
Chiaki often participates in international competitive programming contests. The time zone becomes a big problem.
Given a time in Beijing time (UTC +8), Chiaki would like to know the time in another time zone ss.
Input
There are multiple test cases. The first line of input contains an integer TT (1≤T≤1061≤T≤106), indicating the number of test cases. For each test case:
The first line contains two integers aa, bb (0≤a≤23,0≤b≤590≤a≤23,0≤b≤59) and a string ss in the format of "UTC+X'', "UTC-X'', "UTC+X.Y'', or "UTC-X.Y'' (0≤X,X.Y≤14,0≤Y≤90≤X,X.Y≤14,0≤Y≤9).
Output
For each test, output the time in the format of hh:mmhh:mm (24-hour clock).
Sample Input
3
11 11 UTC+8
11 12 UTC+9
11 23 UTC+0
Sample Output
11:11
12:12
03:23
題意:
有一個(gè)中國的大老板經(jīng)常全球各地跑,每次去別的國家他都要重新調(diào)整他手上那閃閃 發(fā)光的勞力士手表上的時(shí)間围橡,他那枯燥且乏味的生活因此也變得如此生動(dòng)暖混。于是乎他找到了 你并示意了一下他手中的勞力士手表想要你幫他的勞力士手表編個(gè)程序,方便他每次出國調(diào) 整手表上的時(shí)間翁授。即給定北京時(shí)間(東八區(qū)時(shí)間)求目標(biāo) X.Y 時(shí)區(qū)的時(shí)間拣播。
思路:
模擬計(jì)算時(shí)區(qū),但是聽說先將時(shí)間調(diào)整到零時(shí)區(qū)會(huì)更好做收擦。
題解:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
for( int T ; scanf( "%d" , &T )==1 ; ){
while( T-- ){
int a,b;
scanf( "%d%d" , &a , &b );
char s[25];
scanf( "%s" , s );
int x = 0,y = 0;
int len = strlen(s);
if( s[len-2]=='.' )
y = y*10+s[len-1]-'0';
for( int i=4 ; i<len&&s[i]!='.' ; i++ )
x = x*10+s[i]-'0';
a -= 8; y = y*6;
if( s[3]=='+' ) a += x,b += y;
else a -= x,b -= y;
if( b<0 ) a--,b += 60;
if( b>=60 ) a++,b -= 60;
if( a>=24 ) a -= 24;
if( a<0 ) a += 24;
printf( "%02d:%02d\n" , a , b );
}
}
return 0;
}
我參考的博客:https://www.cnblogs.com/lesroad/p/9367963.html
放上大佬的代碼來對比:
#include<vector>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<algorithm>
#include<stdlib.h>
#define ll __int64
using namespace std;
const double eps=1e-7;
const int maxn=300050;
char gd[6];
int main(){
int t, h, m;
char s[10];
cin>>t;
while(t--)
{
scanf("%d%d%s", &h, &m, s);
h = h*60+m;
int op = s[3]=='+'?1:-1;
double x;
sscanf(s+4, "%lf", &x);
x = (int)(x*10+0.005);
int cha = x*6*op-8*60;
h = (h+cha)%(24*60);
if(h < 0) h += 24*60;
printf("%02d:%02d\n", h/60, h%60);
}
return 0;
}
F - Four Operations
Little Ruins is a studious boy, recently he learned the four operations!
Now he want to use four operations to generate a number, he takes a string which only contains digits '1' - '9', and split it into 55 intervals and add the four operations '+', '-', '*' and '/' in order, then calculate the result(/ used as integer division).
Now please help him to get the largest result.
Input
First line contains an integer TT, which indicates the number of test cases.
Every test contains one line with a string only contains digits '1'- '9'.
Limits
1≤T≤1051≤T≤105
5≤length of string≤205≤length of string≤20
Output
For every test case, you should output 'Case #x: y', where x indicates the case number and counts from 1 and y is the result.
Sample Input
1
12345
Sample Output
Case #1: 1
題意:
經(jīng)過時(shí)間的推移贮配,90 后常做的口算本日益的變態(tài)了起來到了, 00 后這一代這個(gè)口算本 已經(jīng)不是人能做的了,這件事情灰太狼非常有發(fā)言權(quán)塞赂。小灰灰這個(gè) 00 后開始小學(xué)了泪勒,每天 都有寫不完的作業(yè)和寫不完的變態(tài)口算本,都把小灰灰寫哭了宴猾≡泊妫灰太狼心想這口算本有這么 變態(tài)嗎,于是拿起一看上面這么寫著:1 秒時(shí)間限制做 100000 到以下口算題仇哆。每道口算題 的規(guī)格是這樣子的沦辙,給一串?dāng)?shù)字要求在里面依次插入+,-讹剔,*油讯,/變成一個(gè)表達(dá)式,求表達(dá)式 的最大值延欠∧岸遥灰太狼一籌莫展于是乎找到了你,求你這個(gè)編程大佬寫個(gè)程序幫忙解決這個(gè)問題衫冻。
題解:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
int T;
scanf( "%d" , &T );
for( int cas=1 ; cas<=T ; cas++ ){
char s[25]; scanf( "%s" , s );
ll ans = -10000; int len = strlen(s);
for( int i=1 ; i<=3&&i+4<=len ; i++ ){
ll a=0,b=0,c=0,d=0,e=0;
for( int j=0 ; j<len-i-3 ; j++ )
a = a*10+s[j]-'0';
for( int j=len-i-3 ; j<len-i-2 ; j++ )
b = b*10+s[j]-'0';
for( int j=len-i-2 ; j<len-i-1 ; j++ )
c = c*10+s[j]-'0';
for( int j=len-i-1 ; j<len-i ; j++ )
d = d*10+s[j]-'0';
for( int j=len-i ; j<len ; j++ )
e = e*10+s[j]-'0';
ans = max( ans , a+b-c*d/e );
}
for( int i=1 ; i<=3&&i+4<=len ; i++ ){
ll a=0,b=0,c=0,d=0,e=0;
for( int j=0 ; j<1 ; j++ )
a = a*10+s[j]-'0';
for( int j=1 ; j<len-i-2 ; j++ )
b = b*10+s[j]-'0';
for( int j=len-i-2 ; j<len-i-1 ; j++ )
c = c*10+s[j]-'0';
for( int j=len-i-1 ; j<len-i ; j++ )
d = d*10+s[j]-'0';
for( int j=len-i ; j<len ; j++ )
e = e*10+s[j]-'0';
ans = max( ans , a+b-c*d/e );
}
printf( "Case #%d: %lld\n" , cas , ans );
}
return 0;
}
思路:
先觀察一下運(yùn)算符號(hào)的順序诀紊,再腦補(bǔ)一下怎樣才可以使答案盡量最大化谒出。然后很溫馨
的獻(xiàn)上一組測試數(shù)據(jù) 111991隅俘。
參考博客:https://www.cnblogs.com/Simon-X/p/6040672.html(一個(gè)只有5個(gè)部分,可以寫成A+B-C*D/E笤喳,要使結(jié)果最大为居,則A+B最大,C*D/E最小杀狡,A+B最大蒙畴,加號(hào)要么在第一位數(shù)后面,要么在最后一位數(shù)前面。C*D/E最小膳凝,C和D都是1位數(shù)碑隆,E只有可能是1~3位數(shù),到3位數(shù)的時(shí)候已經(jīng)為0了蹬音。所以最多只要就算三次即可上煤,注意初始化。)
其他參考博客:https://www.cnblogs.com/Roni-i/p/7505345.html
https://blog.csdn.net/u010568270/article/details/52965718
大佬的解題方法的對比:(反正我是看不懂了)
#include<vector>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<algorithm>
#include<stdlib.h>
#define ll __int64
using namespace std;
const double eps=1e-7;
const int maxn=300050;
char a[25];
int main(){
int n;
int T,len,i,j;
ll sum,l,r,L,L10,R,R10;
scanf("%d",&T);
int count=0;
while(T--){
a[0]=0;
scanf("%s",a);
sum=(ll)1<<63;//
len=strlen(a);
//
L=0,L10=1;
for(int i=0;i<len-3;++i,L10*=10)
L=L*10+a[i]-'0';
L10/=10;
//
R=0;R10=1;
j=min(3,len-4);
for(int i=1;i<=j;++i){
R=(a[len-i]-'0')*R10+R;
R10*=10;
l=max(L/L10+L%L10, L/10+L%10);
L10/=10;L/=10;
r=(a[len-i-2]-'0')*(a[len-i-1]-'0')/R;
sum=max(sum,l-r);
}
printf("Case #%d: ",++count);
printf("%I64d\n",sum);
}
return 0;
}
G - tree
There is a tree(the tree is a connected graph which contains nn points and n?1n?1 edges),the points are labeled from 1 to nn,which edge has a weight from 0 to 1,for every point i∈[1,n]i∈[1,n],you should find the number of the points which are closest to it,the clostest points can contain ii itself.
Input
the first line contains a number T,means T test cases.
for each test case,the first line is a nubmer nn,means the number of the points,next n-1 lines,each line contains three numbers u,v,wu,v,w,which shows an edge and its weight.
T≤50,n≤105,u,v∈[1,n],w∈[0,1]T≤50,n≤105,u,v∈[1,n],w∈[0,1]
Output
for each test case,you need to print the answer to each point.
in consideration of the large output,imagine ansiansi is the answer to point ii,you only need to output,ans1 xor ans2 xor ans3.. ansnans1 xor ans2 xor ans3.. ansn.
Sample Input
1
3
1 2 0
2 3 1
Sample Output
1
in the sample.
,so you need to output 1.
題意:
螞蟻森林在阿拉贊種了好多樹著淆,所以我們也做一個(gè)樹的題應(yīng)應(yīng)景劫狠。題目是這樣的:一 顆樹有 n 個(gè)點(diǎn) n-1 條邊,n-1 條邊中每條邊的邊權(quán)不是 0 就是 1永部。求距離各個(gè)點(diǎn)的距離 0 的 點(diǎn)數(shù)異或和独泞。
思路:
這題是明則考樹,暗則考并查集苔埋。邊權(quán)為 0 的邊做并查集揉作一團(tuán)懦砂。
題解
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long LL;
const int Size=100010;
int pre[Size];
int num[Size];
int Find(int x){
if(x!=pre[x]) pre[x]=Find(pre[x]);
return pre[x];
}
void mix(int x,int y){
int fx=Find(x);
int fy=Find(y);
if(fx!=fy){
pre[fy]=fx;
num[fx]+=num[fy];
}
}
int main(){
int t,i,n,u,v,w;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(i=1;i<=n;i++) pre[i]=i,num[i]=1;
for(i=1;i<n;i++){
scanf("%d%d%d",&u,&v,&w);
if(w==0) mix(u,v);
}
int ans=0;
for(i=1;i<=n;i++) if(i==Find(i)&&num[i]%2) ans^=num[i];
printf("%d\n",ans);
}
return 0;
}
H - Digital Deletions
<dd style="box-shadow: rgb(136, 136, 136) 3px 3px 6px; background-color: rgba(210, 210, 255, 0.5); padding: 20px; border-radius: 10px; font-family: Merriweather, serif; font-size: 18px; -webkit-font-smoothing: antialiased; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
Digital deletions is a two-player game. The rule of the game is as following.
Begin by writing down a string of digits (numbers) that's as long or as short as you like. The digits can be 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 and appear in any combinations that you like. You don't have to use them all. Here is an example:
On a turn a player may either:
Change any one of the digits to a value less than the number that it is. (No negative numbers are allowed.) For example, you could change a 5 into a 4, 3, 2, 1, or 0.
Erase a zero and all the digits to the right of it.
The player who removes the last digit wins.
The game that begins with the string of numbers above could proceed like this:
Now, given a initial string, try to determine can the first player win if the two players play optimally both.
<dt style="font-weight: bold; margin-top: 20px; padding-left: 35px; color: rgb(0, 0, 0); font-family: 楷體; font-size: medium; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Input</dt>
The input consists of several test cases. For each case, there is a string in one line.
The length of string will be in the range of [1,6]. The string contains only digit characters.
Proceed to the end of file.
Output
Output Yes in a line if the first player can win the game, otherwise output No.
Sample Input
0
00
1
20
Sample Output
Yes
Yes
No
No
題意;
博弈老玩家+博弈云玩家 Alice 和 Bob 又回來了组橄。她(他)們還帶回來了一款新游戲孕惜, 名日數(shù)字刪除。這個(gè)游戲是在數(shù)字串上進(jìn)行的晨炕,每次玩家都可以選擇任意位置上的數(shù)字衫画。如 果該位置上的數(shù)字為 0 則刪除該數(shù)以及該數(shù)后面的所有數(shù)字,若為非 0 則可以減小這個(gè)數(shù)字 比如數(shù)字 5 可以減小為 4瓮栗,3削罩,2,1费奸,0弥激。Alice 和 Bob 這兩個(gè)博弈老玩家又?jǐn)[出一副牛逼哄 哄的樣子,吵著鬧著要做云玩家愿阐,忘了說這個(gè)游戲也是不能操作的玩家算輸微服。
題意:
對于首位為 0 的先手秒贏,其他情況 SG 函數(shù)暴力跑一跑缨历。
題解:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
const int Size=1000010;
int SG[Size];
void init(){
memset(SG,0,sizeof(SG));
int i,j,t; SG[0]=1;
for(i=1;i<1000000;i++){
int temp=i,p=1;
while(temp){
t=temp%10;
if(t==0){
if(SG[temp/10]==0) SG[i]=1;
}else{
if(temp<10){
for(j=1;j<t;j++){
if(SG[i-j*p]==0) SG[i]=1;
}
}else{
for(j=1;j<=t;j++){
if(SG[i-j*p]==0) SG[i]=1;
}
}
}
temp/=10,p*=10;
}
}
}
int main(){
init();
char in[10];
while(scanf("%s",in)!=EOF){
if(in[0]=='0'){
printf("Yes\n");
}else{
int temp=0,i;
for(i=0;in[i]!='\0';i++) temp=temp*10+in[i]-'0';
if(SG[temp]) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}
I - First One
soda has an integer array a1,a2,…,ana1,a2,…,an. Let S(i,j)S(i,j) be the sum of ai,ai+1,…,ajai,ai+1,…,aj. Now soda wants to know the value below:
∑i=1n∑j=in(?log2S(i,j)?+1)×(i+j)
∑i=1n∑j=in(?log2?S(i,j)?+1)×(i+j)
Note: In this problem, you can consider log20log2?0 as 0.
Input
There are multiple test cases. The first line of input contains an integer TT, indicating the number of test cases. For each test case:
The first line contains an integer nn (1≤n≤105)(1≤n≤105), the number of integers in the array.
The next line contains nn integers a1,a2,…,ana1,a2,…,an (0≤ai≤105)(0≤ai≤105).
Output
For each test case, output the value.
Sample Input
1
2
1 1
Sample Output
12
題意:
眾所周知出久是 OneForAll 第 9 代丐幫長老以蕴,不是非常擅長學(xué)習(xí)但是擅長惹毛爆豪。 今天出久又惹毛爆豪了辛孵,于是乎學(xué)霸爆豪反手甩了一道數(shù)學(xué)題過來丛肮。這個(gè)數(shù)學(xué)題是以序列為 背景的,給定序列求:∑i=1n∑j=in(?log2S(i,j)?+1)×(i+j)魄缚,其中 S(i,j)表示區(qū)間[i,j]的區(qū)間和宝与。
思路:
這題暴力求取肯定是不行的焚廊,但是 log2S(i,j)的取值是不到 50 個(gè)。枚舉 log2S(i,j) 的取值然后再計(jì)算习劫,復(fù)雜度可行咆瘟。
題解:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 100010;
LL sum[maxn],p[110];
int T,n;
LL cal( LL L , LL R )
{
int l=1,r=0;
LL res = 0;
for ( int i=1 ; i<=n ; i++ )
{
if ( l<i ) l=i;
if ( r<i-1 ) r=i-1;
while( l<=n&&sum[l]-sum[i-1]<L ) l++;
while( r+1<=n&&sum[r+1]-sum[i-1]<R ) r++;
if ( l>r ) continue;
if ( sum[l]-sum[i-1]<L||sum[l]-sum[i-1]>=R ) continue;
if ( sum[r]-sum[i-1]<L||sum[r]-sum[i-1]>=R ) continue;
res += (LL)(r-l+1)*i+(LL)(l+r)*(r-l+1)/2;
}
return res;
}
int main()
{
p[0] = 1; sum[0] = 0;
for ( int i=1 ; i<=50 ; i++ )
p[i] = p[i-1]*2;
scanf ( "%d" , &T );
while ( T-- )
{
scanf ( "%d" , &n );
for ( int i=1 ; i<=n ; i++ )
{
int x; scanf ( "%d" , &x );
sum[i] = sum[i-1]+x;
}
LL res = 0;
for ( int i=1 ; i<=50 ; i++ )
res += (LL)i*cal(p[i-1],p[i]);
res += cal(0,1);
printf ( "%lld\n" , res );
}
return 0;
}
J - A hard puzzle
lcy gives a hard puzzle to feng5166,lwg,JGShining and Ignatius: gave a and b,how to know the a^b.everybody objects to this BT problem,so lcy makes the problem easier than begin.
this puzzle describes that: gave a and b,how to know the a^b's the last digit number.But everybody is too lazy to slove this problem,so they remit to you who is wise.
Input
There are mutiple test cases. Each test cases consists of two numbers a and b(0<a,b<=2^30)
Output
For each test case, you should output the a^b's last digit number.
Sample Input
7 66
8 800
Sample Output
9
6
題意:求 a^b 得最后一位
思路:快速冪或者循環(huán)節(jié)]
我參考的博客:https://blog.csdn.net/nvliba/article/details/48676659
題解:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
using namespace std;
#define INF 0x7fffffff
const int iNF=1e8;
int POW(int a,int b){
int result=1;
int x=a%10;
while(b){
if(b&1) result=result*x%10;
x=x*x%10;
b>>=1;
}
return result;
}
int main(){
int a,b;
while(~scanf("%d%d",&a,&b)){
printf("%d\n",POW(a,b));
}
return 0;
}
K - Kingdom of Obsession
There is a kindom of obsession, so people in this kingdom do things very strictly.
They name themselves in integer, and there are nn people with their id continuous (s+1,s+2,?,s+n)(s+1,s+2,?,s+n) standing in a line in arbitrary order, be more obsessively, people with id xx wants to stand at ythyth position which satisfy
xmody=0
xmody=0
Is there any way to satisfy everyone's requirement?
Input
First line contains an integer TT, which indicates the number of test cases.
Every test case contains one line with two integers nn, ss.
Limits
1≤T≤1001≤T≤100.
1≤n≤1091≤n≤109.
0≤s≤1090≤s≤109.
Output
For every test case, you should output 'Case #x: y', where x indicates the case number and counts from 1 and y is the result string.
If there is any way to satisfy everyone's requirement, y equals 'Yes', otherwise y equals 'No'.
Sample Input
2
5 14
4 11
Sample Output
Case #1: No
Case #2: Yes
題意:
將 n 個(gè)數(shù)字 s+1,s+2诽里,s+3搞疗,。须肆。匿乃。,s+n豌汇,安排在 1幢炸,2,3拒贱,宛徊。。逻澳。闸天,n 位置上秽褒,要求每個(gè)數(shù) 字能夠整除它的位置刹勃。
思路:
小于等于 n 的數(shù)字安排在和其數(shù)字相等的位置,大于 n 的數(shù)字另外安排旅挤。另外安排 的項(xiàng)數(shù)超過 100 個(gè)則肯定安排不上瓤逼,因?yàn)檫B續(xù) 100 個(gè)數(shù)字一定有兩個(gè)質(zhì)數(shù)笼吟。最后二分圖匹配
一下,看是否能完全匹配上霸旗。
題解:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int tol,head[110];
struct edge{
int to,next;
}es[10010];
void init(){
tol = 0; memset( head , -1 , sizeof(head) );
}
void addedge( int u , int v ){
es[tol].to = v;
es[tol].next = head[u];
head[u] = tol++;
}
int linker[110],un; bool used[110];
bool dfs( int u ){
for( int i=head[u] ; i!=-1 ; i=es[i].next ){
int v = es[i].to;
if( !used[v] ){
used[v] = true;
if( linker[v]==-1||dfs( linker[v] ) ){
linker[v] = u;
return true;
}
}
}
return false;
}
int hungry(){
int res = 0;
memset( linker , -1 , sizeof(linker) );
for( int u=1 ; u<=un ; u++ ){
memset( used , false , sizeof(used) );
if( dfs(u) ) res++;
}
return res;
}
int main(){
int T;
scanf( "%d" , &T );
for( int cas=1 ; cas<=T ; cas++ ){
int n,s; scanf( "%d%d" , &n , &s );
if( min( n , s )>=100 ){
printf( "Case #%d: No\n" , cas );
}else{
init(); un = min( n , s );
for( int i=max( s+1 , n+1 ) ; i<=n+s ; i++ ){
for( int j=1 ; j<=min( n , s ) ; j++ ){
if( i%j==0 ) addedge( i-max( s , n ) , j );
}
}
if( hungry()==un ) printf( "Case #%d: Yes\n" , cas );
else printf( "Case #%d: No\n" , cas );
}
}
return 0;
}