- ( 0은 빈칸, 1은 벽이므로 area index는 2부터 시작, index 유지를 위해 0 2개 삽입)
2. 전체를 탐색하면서 벽을 만날 경우 4방향에 대해
- 1이 아니면 빈 공간이 index로 칠해진 것. 해당 index의 size를 ArrayList로부터 가져와 누적한다.
- 1이면 벽, 무시한다
3. 각 방향의 area index가 같다면, 두번 더해선 안된다.
- 4개의 값이므로, 각각 이전 값들과 다를 경우에만 누적한다 ( 가독성, 확장성은 좋지 않지만, 성능 효율적 )
- set에 다 던져넣고 하나씩 꺼내며 쓴다 ( 가독성, 확장성은 좋지만, 성능 비효율적)
4. 출력할 때 println등을 이용하면 최악 1000*1000번 출력하게되므로, buffer 이용이 필수적이다
+ 4번 print구간은 3번 반복문에 그대로 삽입할 수 있다
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class Main{
public static void main(String[] args)throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int n = pint(st.nextToken());
int m = pint(st.nextToken());
map=new int[n+2][m+2];
int[][]ansMap=new int[n+2][m+2];
//외곽 padding
for (int i = 0; i < n+2; i++) {
map[i][0]=1;map[i][m+1]=1;
}
for (int i = 0; i < m+2; i++) {
map[0][i]=1;map[n+1][i]=1;
}
// 1. input
for (int i = 1; i <= n; i++) {
String s = br.readLine();
for (int j = 1; j <= m; j++) {
map[i][j]=s.charAt(j-1)-'0';
}
}
//2. get size by bfs for each area + tagging
ArrayList<Integer>area=new ArrayList<>();
area.add(0);area.add(0);
int idx=2;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if(map[i][j]==0) {
int size=search(idx++, i, j);
area.add(size);
}
}
}
//3. check four-dir of each wall + add if area
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if(map[i][j]==1) {
ansMap[i][j]+=1;
if(map[i+1][j]!=1)
ansMap[i][j]+=area.get(map[i+1][j]);
if(map[i][j+1]!=1 && map[i+1][j]!=map[i][j+1])
ansMap[i][j]+=area.get(map[i][j+1]);
if(map[i-1][j]!=1&& map[i+1][j]!=map[i-1][j] && map[i-1][j]!=map[i][j+1])
ansMap[i][j]+=area.get(map[i-1][j]);
if(map[i][j-1]!=1 && map[i][j-1]!=map[i+1][j]&& map[i][j-1]!=map[i][j+1] && map[i][j-1]!=map[i-1][j])
ansMap[i][j]+=area.get(map[i][j-1]);
}
}
}
//4.print
for (int i = 1; i < n+1; i++) {
for (int j = 1; j < m+1; j++)sb.append(ansMap[i][j]%10);
sb.append("\n");
}System.out.println(sb);
}
static int[][]map;
static int search(int idx, int x, int y) {
int size=1;
map[x][y]=idx;
if(map[x+1][y]==0)size+=search(idx,x+1,y);
if(map[x-1][y]==0)size+=search(idx,x-1,y);
if(map[x][y+1]==0)size+=search(idx,x,y+1);
if(map[x][y-1]==0)size+=search(idx,x,y-1);
return size;
}
static int pint(String s) {
return Integer.parseInt(s);
}
}
그렇게 받은 pin 정보는, 이전에 취득했던 requestToken과 함께 다시 한번 트위터에게 제출됩니다.
getOAuthAccessToken함수를 이용합니다.
이 과정까지 성공적으로 완료했다면, 정상적으로 AccessToken을 획득한 것으로 이제 이 계정은 제 맘대로 할 수 있는 겁니다. (안됩니다)
twitter.setOAuthAccessToken(finalAccessToken);
try {
//계정명 획득
User user = twitter.verifyCredentials();
System.out.println(user.getScreenName());
//계정에 트윗 등록
String msg = "this is test tweet from application";
Status status = twitter.updateStatus(msg);
}catch(Exception e) {
e.printStackTrace();
}
정상적으로 출력 / 트윗되었다
다음 코드와 같이, AccessToken을 Set해주기만 하면 사용자 ID를 가져올 수도 있고, 원하는 문자열로 트윗을 보낼 수도 있습니다.
4. AccessToken을 저장해 둬 재사용 가능하게 하기
여기까지만 하면, 매번 AccessToken을 획득해야한다는 수고로운 일이 생깁니다.
물론 그럴 필요는 없습니다. AccessToken만 저장해두면 언제든지 꺼내서 재사용이 가능해집니다.
위에서 획득한 AccessToken은 Consumer key/secret처럼 key/secret 두가지 token으로 되어 있습니다.
getToken() 함수와, getTokenSecret()함수가 각 token을 획득 할 수 있으며, 플젝에 직접 박아놓든, DB에 저장하거나 한 후 필요할 때 조회하면 됩니다.
twitter = TwitterFactory.getSingleton();
finalAccessToken=new AccessToken(TwitterInfo.getInstance().getAccessToken(),
TwitterInfo.getInstance().getAccessSecret());
twitter.setOAuthAccessToken(finalAccessToken);
try {
User user = twitter.verifyCredentials();
System.out.println(user.getScreenName());
String msg = "this is test tweet from application";
Status status = twitter.updateStatus(msg);
}catch(Exception e) {
e.printStackTrace();
}
저는 TwitterInfo class에 값을 직접 저장했으며, consumer token과 함께 생성자에서 호출해 설정하는 식으로 마무리했습니다.
1. A에서 B로 선분을 그으려 할 때, 이미 A와 B가 같은 집합에 속한다면 사이클이 생성된다
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main{
public static void main(String[] args)throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int n = pint(st.nextToken());
int m = pint(st.nextToken());
init(n);
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine(), " ");
int x = pint(st.nextToken());
int y = pint(st.nextToken());
if(!union(x,y)) {
System.out.println(i+1);
break;
}
else if(i==m-1) {
System.out.println(0);
}
}
}
static int[] parents;
static void init(int n) {
parents=new int[n];
for (int i = 0; i < n; i++) {
parents[i]=i;
}
}
static int find(int n) {
if(parents[n]!=n)return parents[n]=find(parents[n]);
return n;
}
static boolean union(int x, int y) {
int px=find(x), py=find(y);
if(px==py)return false;
parents[px]=py;
return true;
}
static int pint(String s) {
return Integer.parseInt(s);
}
}